1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
use crate::Symbol; use syn::parse::{Parse, ParseBuffer}; use syn::{AttributeArgs, DeriveInput, Error, Meta}; pub trait AnnotationStructure { fn get_path() -> Symbol where Self: Sized; fn from_meta(input: &Meta) -> Result<Self, syn::Error> where Self: std::marker::Sized; fn from_attribute_args(input: AttributeArgs) -> Result<Self, syn::Error> where Self: std::marker::Sized; } pub struct AnnotationStructures<T: AnnotationStructure> { pub attrs: Vec<T>, } impl<T: AnnotationStructure> AnnotationStructures<T> { pub fn from_derive_input(derive_input: &DeriveInput) -> Result<Self, Error> { let attributes: Vec<T> = derive_input .attrs .iter() .map(|attr| match attr.parse_meta() { Ok(meta) => T::from_meta(&meta), Err(e) => Err(e), }) .collect::<Result<Vec<T>, Error>>()?; Ok(AnnotationStructures { attrs: attributes }) } } impl<T: AnnotationStructure> Parse for AnnotationStructures<T> { fn parse(input: &ParseBuffer) -> Result<Self, Error> { let derive_input = DeriveInput::parse(&input)?; Self::from_derive_input(&derive_input) } }