-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.rs
92 lines (78 loc) · 2.04 KB
/
build.rs
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
use std::{
env,
fs::OpenOptions,
io::{
self,
BufWriter,
Write,
},
num::NonZeroUsize,
path::{
Path,
PathBuf,
},
};
use quote::{
format_ident,
quote,
};
use syn::Index;
fn tuple<W: Write>(mut w: W, i: NonZeroUsize) -> Result<(), io::Error> {
let i = i.get();
let parsers = (0usize..i).map(|i| format_ident!("P{}", i));
let tuple = parsers.clone();
let generics = parsers.clone();
let generics_where = parsers;
let tuple = quote! {
#(#tuple,)*
};
let generics = quote! {
#(#generics),*
};
let tokens = (0usize..i).map(|i| format_ident!("O{}", i));
let generics_where = quote! {
#(#generics_where: Parse<Stream, Context, Token = #tokens>),*
};
let tokens2 = (0usize..i).map(|i| format_ident!("O{}", i));
let tokens3 = (0usize..i).map(|i| format_ident!("O{}", i));
let tokens4 = (0usize..i).map(|i| format_ident!("token_{}", i));
let matches = (0usize..i).map(Index::from).map(|i| {
let token = format_ident!("token_{}", i);
quote! {
let Success { token: #token, stream } = self.#i.parse(stream)?;
}
});
let codegen = quote! {
impl<#(#tokens2: Debug,)* #generics, Stream, Context> Parse<Stream, Context> for (#tuple)
where
Stream: Streaming,
#generics_where
{
type Token = (#(#tokens3,)*);
fn parse(&mut self, stream: Stream) -> Parsed<Self::Token, Stream, Context> {
#(#matches)*
Parsed::new_success((#(#tokens4,)*), stream)
}
}
};
write!(w, "{}", rustfmt_wrapper::rustfmt(codegen).unwrap())
}
fn tuples(path: &Path) -> Result<(), io::Error> {
let dest_path = Path::new(path).join("parse_tuple.rs");
let file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&dest_path)?;
let mut buf = BufWriter::new(file);
for i in 1..12 {
tuple(&mut buf, i.try_into().unwrap())?;
}
Ok(())
}
fn main() -> Result<(), io::Error> {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
tuples(&out_dir)?;
Ok(())
}