use quote::ToTokens;
use super::{attr_names::*, util::*};
static ATTR_DOC: &str = "doc";
pub fn extract_doc(attrs: &[syn::Attribute]) -> Vec<String> {
attrs
.iter()
.filter(|attr| {
if let Some(first_seg) = attr.path().segments.first() {
first_seg.ident == ATTR_DOC
} else {
false
}
})
.map(|attr| match attr.meta.clone() {
syn::Meta::Path(_) => panic!("wrong format. expected name value, received path"),
syn::Meta::List(_) => panic!("wrong format. expected name value, received list"),
syn::Meta::NameValue(meta_name_value) => {
if let syn::Expr::Lit(lit_str) = meta_name_value.value {
if meta_name_value.path.is_ident("doc") {
let value = lit_str.lit;
if let Some(tuple) = value
.to_token_stream()
.to_string()
.split_once(char::is_whitespace)
{
remove_backslashes(tuple.1)
} else {
String::new()
}
} else {
panic!("Attribute doesn't have the 'doc' identifier");
}
} else {
panic!("Value is not a string literal");
}
}
})
.collect()
}
pub fn extract_macro_attributes(attrs: &[syn::Attribute]) -> Vec<String> {
let mut macro_attributes = Vec::new();
for a in attrs {
match &a.meta {
syn::Meta::List(list) if list.path.is_ident("derive") => {
for token in list.tokens.clone().into_iter() {
if let proc_macro2::TokenTree::Ident(ident) = token {
macro_attributes.push(ident.to_string());
}
}
}
syn::Meta::Path(path) if path.segments.len() > 1 => {
let path_str = path
.segments
.iter()
.map(|s| s.ident.to_string())
.collect::<Vec<_>>()
.join("::");
macro_attributes.push(path_str);
}
_ => {}
}
}
macro_attributes
}
fn remove_backslashes(input: &str) -> String {
input
.trim_matches('\"')
.replace("\\\"", "\"")
.replace("\\'", "'")
}
pub struct OutputNameAttribute {
pub output_name: String,
}
impl OutputNameAttribute {
pub fn parse(attr: &syn::Attribute) -> Option<Self> {
is_attr_one_string_arg(attr, ATTR_OUTPUT_NAME).map(|arg_str| OutputNameAttribute {
output_name: arg_str,
})
}
}
pub struct TitleAttribute {
pub title: String,
}
impl TitleAttribute {
pub fn parse(attr: &syn::Attribute) -> Option<Self> {
is_attr_one_string_arg(attr, ATTR_TITLE).map(|arg_str| TitleAttribute { title: arg_str })
}
}