typhoon-context-macro 0.1.0-alpha.8

TODO
Documentation
use syn::{
    parse::{Parse, ParseStream},
    parse2, Attribute, Ident, Token, Type,
};

pub struct Argument {
    pub name: Ident,
    pub ty: Type,
}

impl Parse for Argument {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let name: Ident = input.parse()?;
        input.parse::<Token![:]>()?;
        let ty: Type = input.parse()?;

        Ok(Argument { name, ty })
    }
}

pub enum Arguments {
    Values(Vec<Argument>),
    Struct(Ident),
}
impl Parse for Arguments {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        if input.peek2(Token![:]) {
            let mut arguments = Vec::new();
            while input.peek2(Token![:]) {
                let arg: Argument = input.parse()?;
                arguments.push(arg);

                if input.peek(Token![,]) {
                    input.parse::<Token![,]>()?;
                }
            }

            Ok(Arguments::Values(arguments))
        } else {
            Ok(Arguments::Struct(input.parse()?))
        }
    }
}

impl TryFrom<&mut Attribute> for Arguments {
    type Error = syn::Error;

    fn try_from(value: &mut Attribute) -> Result<Self, Self::Error> {
        let tokens = value.meta.require_list()?.tokens.clone();
        parse2::<Arguments>(tokens)
    }
}