Skip to main content

typhoon_syn/
arguments.rs

1use syn::{
2    parse::{Parse, ParseStream},
3    parse2, Attribute, Ident, Token, Type,
4};
5
6#[derive(Clone)]
7pub struct Argument {
8    pub name: Ident,
9    pub ty: Type,
10}
11
12impl Parse for Argument {
13    fn parse(input: ParseStream) -> syn::Result<Self> {
14        let name: Ident = input.parse()?;
15        input.parse::<Token![:]>()?;
16        let ty: Type = input.parse()?;
17
18        Ok(Argument { name, ty })
19    }
20}
21
22pub enum Arguments {
23    Values(Vec<Argument>),
24    Struct(Ident),
25}
26impl Parse for Arguments {
27    fn parse(input: ParseStream) -> syn::Result<Self> {
28        if input.peek2(Token![:]) {
29            let mut arguments = Vec::new();
30            while input.peek2(Token![:]) {
31                let arg: Argument = input.parse()?;
32                arguments.push(arg);
33
34                if input.peek(Token![,]) {
35                    input.parse::<Token![,]>()?;
36                }
37            }
38
39            Ok(Arguments::Values(arguments))
40        } else {
41            Ok(Arguments::Struct(input.parse()?))
42        }
43    }
44}
45
46impl TryFrom<&Attribute> for Arguments {
47    type Error = syn::Error;
48
49    fn try_from(value: &Attribute) -> Result<Self, Self::Error> {
50        let tokens = value.meta.require_list()?.tokens.clone();
51        parse2::<Arguments>(tokens)
52    }
53}