ruma-bot

git clone git://archive.git.mtrnord.blog/MTRNord/ruma-bot.git
Log | Files | Refs

args.rs (2807B)


      1 use std::collections::HashSet;
      2 use syn::{
      3     parse::{Parse, ParseStream},
      4     punctuated::{Pair, Punctuated},
      5     Expr, ExprArray, ExprLit, Ident, Lit, LitStr, Token,
      6 };
      7 
      8 pub enum Arg {
      9     Command(LitStr),
     10     Commands(HashSet<LitStr>),
     11     //DmOnly
     12 }
     13 
     14 impl Parse for Arg {
     15     fn parse(input: ParseStream) -> syn::Result<Self> {
     16         let ident = input.call(Ident::parse)?;
     17         let arg_name = ident.to_string();
     18         match &arg_name[..] {
     19             "command" => {
     20                 if input.peek(Token![=]) {
     21                     let _: Token![=] = input.parse()?;
     22                     Ok(Self::Command(input.parse()?))
     23                 } else {
     24                     Err(input.error("expected `=`"))
     25                 }
     26             }
     27             "commands" => {
     28                 if input.peek(Token![=]) {
     29                     let _: Token![=] = input.parse()?;
     30                     let array: ExprArray = input.parse()?;
     31 
     32                     if !array.attrs.is_empty() {
     33                         return Err(syn::Error::new_spanned(
     34                             &array.attrs[0],
     35                             "attributes are not allowed here",
     36                         ));
     37                     }
     38 
     39                     let commands = array
     40                         .elems
     41                         .into_pairs()
     42                         .map(Pair::into_value)
     43                         .map(|expr| {
     44                             if let Expr::Lit(ExprLit { attrs, lit }) = expr {
     45                                 if !attrs.is_empty() {
     46                                     return Err(syn::Error::new_spanned(
     47                                         &attrs[0],
     48                                         "attributes are not allowed here",
     49                                     ));
     50                                 }
     51 
     52                                 if let Lit::Str(s) = lit {
     53                                     Ok(s)
     54                                 } else {
     55                                     Err(syn::Error::new_spanned(lit, "expected string literal"))
     56                                 }
     57                             } else {
     58                                 Err(syn::Error::new_spanned(expr, "expected string literal"))
     59                             }
     60                         })
     61                         .collect::<Result<_, _>>()?;
     62 
     63                     Ok(Self::Commands(commands))
     64                 } else {
     65                     Err(input.error("expected `=`"))
     66                 }
     67             }
     68             _ => Err(syn::Error::new_spanned(ident, "unknown ruma_bot option")),
     69         }
     70     }
     71 }
     72 
     73 pub struct Args(pub Vec<Arg>);
     74 
     75 impl Parse for Args {
     76     fn parse(input: ParseStream) -> syn::Result<Self> {
     77         let args = Punctuated::<Arg, Token![,]>::parse_terminated(input)?;
     78         Ok(Self(args.into_iter().collect()))
     79     }
     80 }