-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
140 lines (124 loc) · 3.06 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*!
# `ChannelZ`
*/
use argyle::KeyWordsBuilder;
use dactyl::{
NiceU16,
NiceU32,
};
use std::{
io::Write,
path::{
Path,
PathBuf,
},
};
/// # Pre-Compute Arguments and Extensions.
///
/// Because we know all of the target extensions in advance, we can store them
/// as primitives for faster runtime comparison (when crawling paths).
///
/// There are a few other, longer extensions that aren't worth optimizing in
/// this way. They're just dealt with inline in `ext.rs`.
pub fn main() {
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION");
// CLI Arguments.
write_cli();
let out = format!(
r"
/// # Match br/gz.
pub(super) const fn match_encoded(bytes: &[u8]) -> bool {{
if let [.., 0..=46 | 48..=91 | 93..=255, b'.', a, b] = bytes {{
matches!(
u16::from_le_bytes([a.to_ascii_lowercase(), b.to_ascii_lowercase()]),
{}
)
}}
else {{ false }}
}}
/// # Match 2.
const fn match2(ext: u16) -> bool {{ matches!(ext, {}) }}
/// # Match 3.
const fn match3(ext: u32) -> bool {{ matches!(ext, {}) }}
/// # Match 4.
const fn match4(ext: u32) -> bool {{ matches!(ext, {}) }}
",
pat16(&["br", "gz"]),
pat16(&["js", "md"]),
pat32(&[
".bmp", ".css", ".csv", ".doc", ".eot", ".htc", ".htm", ".ico", ".ics",
".mjs", ".otf", ".pdf", ".rdf", ".rss", ".svg", ".ttf", ".txt", ".vcs",
".vtt", ".xml", ".xsl", ".xls", ".yml",
]),
pat32(&["atom", "docx", "html", "json", "wasm", "xhtm", "xlsx", "yaml"]),
);
write(&out_path("channelz-matchers.rs"), out.as_bytes());
}
/// # Output Path.
///
/// Append the sub-path to OUT_DIR and return it.
fn out_path(stub: &str) -> PathBuf {
std::fs::canonicalize(std::env::var("OUT_DIR").expect("Missing OUT_DIR."))
.expect("Missing OUT_DIR.")
.join(stub)
}
/// # U16 Pattern.
///
/// Generate a match pattern of u16 values for the provided two-byte extensions.
fn pat16(ext: &[&str]) -> String {
let mut out = Vec::new();
for i in ext {
let i = i.as_bytes();
assert_eq!(i.len(), 2);
let num = NiceU16::with_separator(
u16::from_le_bytes([i[0], i[1]]),
b'_',
);
out.push(num);
}
out.sort();
out.join(" | ")
}
/// # U32 Pattern.
///
/// Generate a match pattern of u32 values for the provided four-byte
/// extensions.
///
/// Note: this is also used for three-byte extensions; they're just padded with
/// a leading dot.
fn pat32(ext: &[&str]) -> String {
let mut out = Vec::new();
for i in ext {
let i = i.as_bytes();
assert_eq!(i.len(), 4);
let num = NiceU32::with_separator(
u32::from_le_bytes([i[0], i[1], i[2], i[3]]),
b'_',
);
out.push(num);
}
out.sort();
out.join(" | ")
}
/// # Write File.
fn write(path: &Path, data: &[u8]) {
std::fs::File::create(path).and_then(|mut f|
f.write_all(data).and_then(|_| f.flush())
)
.expect("Unable to write file.");
}
/// # Write CLI Arguments.
fn write_cli() {
let mut builder = KeyWordsBuilder::default();
builder.push_keys([
"--clean", "--clean-only",
"--force",
"--no-br",
"--no-gz",
"-h", "--help",
"-p", "--progress",
"-V", "--version",
]);
builder.push_keys_with_values(["-l", "--list"]);
builder.save(out_path("argyle.rs"));
}