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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use super::*;
use gen::TypeReader;
use syn::parse::*;
use syn::*;
#[derive(Debug, Default)]
pub struct BuildMacro {
// TODO: add exports
}
impl BuildMacro {
// TODO: doesn't need to be member of BuildMacro
pub fn into_tokens_string(&self) -> String {
let reader = TypeReader::get();
let ts = reader.gen().fold(TokenStream::new(), |mut accum, n| {
accum.combine(&n);
accum
});
ts.into_string()
}
}
impl Parse for BuildMacro {
fn parse(input: ParseStream) -> Result<Self> {
let mut build = Self::default();
while !input.is_empty() {
let tree: UseTree = input.parse()?;
fn walk(tree: &UseTree, mut namespace: String, build: &mut BuildMacro) -> Result<()> {
fn render_namespace(namespace: &str) -> &str {
if namespace.is_empty() {
"(global namespace)"
} else {
namespace
}
}
match tree {
UseTree::Path(input) => {
if !namespace.is_empty() {
namespace.push('.');
}
namespace.push_str(&input.ident.to_string());
walk(&*input.tree, namespace, build)?;
}
UseTree::Name(input) => {
let reader = TypeReader::get_mut();
let name = input.ident.to_string();
if !reader.import_type(&namespace, &name) {
return Err(Error::new_spanned(
input,
format!(
"`{}.{}` not found in metadata",
render_namespace(&namespace),
name
),
));
}
}
UseTree::Glob(input) => {
let reader = TypeReader::get_mut();
if !reader.import_namespace(&namespace) {
return Err(Error::new_spanned(
input,
format!("`{}` not found in metadata", render_namespace(&namespace)),
));
}
}
UseTree::Group(input) => {
for tree in &input.items {
walk(tree, namespace.clone(), build)?;
}
}
UseTree::Rename(input) => {
return Err(Error::new_spanned(input, "Rename syntax not supported"));
}
}
Ok(())
}
walk(&tree, String::new(), &mut build)?;
if !input.is_empty() {
input.parse::<Token![,]>()?;
}
}
Ok(build)
}
}