intertrait_macros/
args.rs1use std::collections::HashSet;
2
3use syn::bracketed;
4use syn::parse::{Parse, ParseStream, Result};
5use syn::punctuated::Punctuated;
6use syn::{Error, Ident, Path, Token, Type};
7
8#[derive(Hash, PartialEq, Eq)]
9pub enum Flag {
10 Sync,
11}
12
13impl Flag {
14 fn from(ident: &Ident) -> Result<Self> {
15 match ident.to_string().as_str() {
16 "sync" => Ok(Flag::Sync),
17 unknown => {
18 let msg = format!("Unknown flag: {}", unknown);
19 Err(Error::new_spanned(ident, msg))
20 }
21 }
22 }
23}
24
25pub struct Targets {
26 pub flags: HashSet<Flag>,
27 pub paths: Vec<Path>,
28}
29
30impl Parse for Targets {
31 fn parse(input: ParseStream) -> Result<Self> {
32 let mut flags = HashSet::new();
33 let mut paths = Vec::new();
34
35 if input.is_empty() {
36 return Ok(Targets { flags, paths });
37 }
38
39 if input.peek(syn::token::Bracket) {
40 let content;
41 bracketed!(content in input);
42 for ident in Punctuated::<Ident, Token![,]>::parse_terminated(&content)? {
43 if !flags.insert(Flag::from(&ident)?) {
44 let msg = format!("Duplicated flag: {}", ident);
45 return Err(Error::new_spanned(ident, msg));
46 }
47 }
48 }
49
50 if input.is_empty() {
51 return Ok(Targets { flags, paths });
52 }
53
54 paths = Punctuated::<Path, Token![,]>::parse_terminated(input)?
55 .into_iter()
56 .collect();
57
58 Ok(Targets { flags, paths })
59 }
60}
61
62pub struct Casts {
63 pub ty: Type,
64 pub targets: Targets,
65}
66
67impl Parse for Casts {
68 fn parse(input: ParseStream) -> Result<Self> {
69 let ty: Type = input.parse()?;
70 input.parse::<Token![=>]>()?;
71
72 Ok(Casts {
73 ty,
74 targets: input.parse()?,
75 })
76 }
77}