args.rs 1.8 KB

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