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}