use proc_macro2::TokenStream;
use syn::{Attribute, Meta};
pub fn parse_schema_attr(attrs: &[Attribute]) -> Option<TokenStream> {
attrs.iter().find_map(|attr| match &attr.meta {
Meta::List(list) if list.path.is_ident("schema") => Some(list.tokens.clone()),
_ => None
})
}
#[cfg(test)]
mod tests {
use quote::quote;
use syn::{Field, parse_quote};
use super::parse_schema_attr;
fn field(tokens: TokenStreamAlias) -> Field {
Field::parse_named.parse2(tokens).expect("field parses")
}
type TokenStreamAlias = proc_macro2::TokenStream;
use syn::parse::Parser as _;
#[test]
fn extracts_the_token_list() {
let f = field(quote! {
#[schema(value_type = Option<SizeCm>)]
pub size_cm: Option<serde_json::Value>
});
let tokens = parse_schema_attr(&f.attrs).expect("attribute found");
assert_eq!(tokens.to_string(), "value_type = Option < SizeCm >");
}
#[test]
fn absent_attribute_yields_none() {
let f: Field = parse_quote! { pub name: String };
assert!(parse_schema_attr(&f.attrs).is_none());
}
#[test]
fn path_and_name_value_forms_are_ignored() {
let bare = field(quote! {
#[schema]
pub name: String
});
let named = field(quote! {
#[schema = "text"]
pub name: String
});
assert!(parse_schema_attr(&bare.attrs).is_none());
assert!(parse_schema_attr(&named.attrs).is_none());
}
}