1 | use crate::{Error, Result}; |
2 | use proc_macro2::{Ident, Span, TokenStream, TokenTree}; |
3 | |
4 | macro_rules! decl_settings { |
5 | ($($val:expr => $variant:ident),+ $(,)*) => { |
6 | #[derive(PartialEq)] |
7 | pub(crate) enum Setting { |
8 | $($variant),* |
9 | } |
10 | |
11 | fn ident_to_setting(ident: Ident) -> Result<Setting> { |
12 | match &*ident.to_string() { |
13 | $($val => Ok(Setting::$variant),)* |
14 | _ => { |
15 | let possible_vals = [$($val),*] |
16 | .iter() |
17 | .map(|v| format!("`{}`" , v)) |
18 | .collect::<Vec<_>>() |
19 | .join(", " ); |
20 | |
21 | Err(Error::new( |
22 | ident.span(), |
23 | format!("unknown setting `{}`, expected one of {}" , ident, possible_vals))) |
24 | } |
25 | } |
26 | } |
27 | }; |
28 | } |
29 | |
30 | decl_settings! { |
31 | "assert_unwind_safe" => AssertUnwindSafe, |
32 | "allow_not_macro" => AllowNotMacro, |
33 | "proc_macro_hack" => ProcMacroHack, |
34 | } |
35 | |
36 | pub(crate) fn parse_settings(input: TokenStream) -> Result<Settings> { |
37 | let mut input = input.into_iter(); |
38 | let mut res = Settings(Vec::new()); |
39 | loop { |
40 | match input.next() { |
41 | Some(TokenTree::Ident(ident)) => { |
42 | res.0.push(ident_to_setting(ident)?); |
43 | } |
44 | None => return Ok(res), |
45 | other => { |
46 | let span = other.map_or(Span::call_site(), |tt| tt.span()); |
47 | return Err(Error::new(span, "expected identifier" .to_string())); |
48 | } |
49 | } |
50 | |
51 | match input.next() { |
52 | Some(TokenTree::Punct(ref punct)) if punct.as_char() == ',' => {} |
53 | None => return Ok(res), |
54 | other => { |
55 | let span = other.map_or(Span::call_site(), |tt| tt.span()); |
56 | return Err(Error::new(span, "expected `,`" .to_string())); |
57 | } |
58 | } |
59 | } |
60 | } |
61 | |
62 | pub(crate) struct Settings(Vec<Setting>); |
63 | |
64 | impl Settings { |
65 | pub(crate) fn is_set(&self, setting: Setting) -> bool { |
66 | self.0.iter().any(|s: &Setting| *s == setting) |
67 | } |
68 | |
69 | pub(crate) fn set(&mut self, setting: Setting) { |
70 | self.0.push(setting) |
71 | } |
72 | } |
73 | |