1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
use inflections::Inflect;
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use syn_codegen::{Data, Definitions, Features, Node};
pub const TERMINAL_TYPES: &[&str] = &["Span", "Ident"];
pub fn under_name(name: &str) -> Ident {
Ident::new(&name.to_snake_case(), Span::call_site())
}
pub fn traverse(
defs: &Definitions,
node: fn(&mut TokenStream, &mut TokenStream, &Node, &Definitions),
) -> (TokenStream, TokenStream) {
let mut types = defs.types.clone();
for terminal in TERMINAL_TYPES {
types.push(Node {
ident: terminal.to_string(),
features: Features::default(),
data: Data::Private,
exhaustive: true,
});
}
types.sort_by(|a, b| a.ident.cmp(&b.ident));
let mut traits = TokenStream::new();
let mut impls = TokenStream::new();
for s in types {
if s.ident == "Reserved" {
continue;
}
let features = &s.features.any;
let features = match features.len() {
0 => quote!(),
1 => quote!(#[cfg(feature = #(#features)*)]),
_ => quote!(#[cfg(any(#(feature = #features),*))]),
};
traits.extend(features.clone());
impls.extend(features);
node(&mut traits, &mut impls, &s, defs);
}
(traits, impls)
}
|