pyro_macro/module/
parse.rs1use syn::{
2 Ident, Result, Token, parenthesized,
3 parse::{Parse, ParseStream},
4 punctuated::Punctuated,
5};
6
7pub enum OutputSpec {
9 SingleField(Ident),
11 TupleFields(Vec<Ident>),
13 Struct,
15}
16
17pub struct ModuleAttrs {
19 pub output: OutputSpec,
20}
21
22impl Parse for ModuleAttrs {
23 fn parse(input: ParseStream) -> Result<Self> {
24 let ident: Ident = input.parse()?;
26 if ident != "output" {
27 return Err(syn::Error::new(ident.span(), "Expected `output = ...`"));
28 }
29
30 input.parse::<Token![=]>()?;
31
32 let output = if input.peek(syn::token::Paren) {
34 let content;
36 parenthesized!(content in input);
37 let fields: Punctuated<Ident, Token![,]> =
38 content.parse_terminated(Ident::parse, Token![,])?;
39 OutputSpec::TupleFields(fields.into_iter().collect())
40 } else {
41 let name: Ident = input.parse()?;
43 let name_str = name.to_string();
44
45 if name_str
47 .chars()
48 .next()
49 .map(|c| c.is_uppercase())
50 .unwrap_or(false)
51 {
52 OutputSpec::Struct
53 } else {
54 OutputSpec::SingleField(name)
55 }
56 };
57
58 Ok(ModuleAttrs { output })
59 }
60}