This commit is contained in:
2025-11-14 20:45:52 +00:00
parent 59aa99ced9
commit 824dacacaa
+9 -25
View File
@@ -335,32 +335,16 @@ fn parse_impl(item_impl: &ItemImpl) -> Option<RustDecl> {
/// Handles both `///` comments (converted to `#[doc = "..."]` by syn) /// Handles both `///` comments (converted to `#[doc = "..."]` by syn)
/// and explicit `#[doc = "..."]` attributes. /// and explicit `#[doc = "..."]` attributes.
fn extract_docstring(attrs: &[Attribute]) -> Option<String> { fn extract_docstring(attrs: &[Attribute]) -> Option<String> {
let mut docs = Vec::new(); // Convert the attributes token stream back to sourcelike text.
let text = attrs
.iter()
.map(|a| a.tokens.to_string())
.collect::<Vec<_>>()
.join("\n");
for attr in attrs { let re = Regex::new(r#"(?m)^\s*(?:///|#\[\s*doc\s*=\s*")(.+?)(?:")?$"#).ok()?;
// `path()` is the correct method; `path` is a field re.captures(&text)
if attr.path().is_ident("doc") { .and_then(|c| c.get(1).map(|m| m.as_str().to_string()))
// #[doc = "…"]
if let Ok(meta) = attr.parse_meta() {
if let syn::Meta::NameValue(nv) = meta {
// The value is an `Expr`. Pull out a string literal.
if let syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Str(lit_str),
..
}) = nv.value
{
docs.push(lit_str.value());
}
}
}
}
}
if docs.is_empty() {
None
} else {
Some(docs.join("\n"))
}
} }
fn parse_mod(item_mod: &ItemMod) -> Option<RustDecl> { fn parse_mod(item_mod: &ItemMod) -> Option<RustDecl> {