annotation_rs/
traits.rs

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