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}