Skip to content

Commit fa7a0ec

Browse files
authored
Merge pull request uutils#2962 from Dr-Emann/phf_dispatch
Use a PHF map for util_map()
2 parents ff4ac20 + f9f7e7d commit fa7a0ec

File tree

6 files changed

+98
-82
lines changed

6 files changed

+98
-82
lines changed

.vscode/cspell.dictionaries/jargon.wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ canonicalize
1111
canonicalizing
1212
codepoint
1313
codepoints
14+
codegen
1415
colorizable
1516
colorize
1617
coprime

Cargo.lock

Lines changed: 46 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ test = [ "uu_test" ]
247247
[dependencies]
248248
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
249249
clap_complete = "3.0"
250+
phf = "0.10.1"
250251
lazy_static = { version="1.3" }
251252
textwrap = { version="0.14", features=["terminal_size"] }
252253
uucore = { version=">=0.0.11", package="uucore", path="src/uucore" }
@@ -387,6 +388,9 @@ nix = "0.23.1"
387388
rust-users = { version="0.10", package="users" }
388389
unix_socket = "0.5.0"
389390

391+
[build-dependencies]
392+
phf_codegen = "0.10.0"
393+
390394
[[bin]]
391395
name = "coreutils"
392396
path = "src/bin/coreutils.rs"

build.rs

Lines changed: 45 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ pub fn main() {
1212
println!("cargo:rustc-cfg=build={:?}", profile);
1313
}
1414

15-
let env_feature_prefix: &str = "CARGO_FEATURE_";
16-
let feature_prefix: &str = "feat_";
17-
let override_prefix: &str = "uu_";
15+
const ENV_FEATURE_PREFIX: &str = "CARGO_FEATURE_";
16+
const FEATURE_PREFIX: &str = "feat_";
17+
const OVERRIDE_PREFIX: &str = "uu_";
1818

1919
let out_dir = env::var("OUT_DIR").unwrap();
2020
// println!("cargo:warning=out_dir={}", out_dir);
@@ -25,16 +25,16 @@ pub fn main() {
2525

2626
let mut crates = Vec::new();
2727
for (key, val) in env::vars() {
28-
if val == "1" && key.starts_with(env_feature_prefix) {
29-
let krate = key[env_feature_prefix.len()..].to_lowercase();
28+
if val == "1" && key.starts_with(ENV_FEATURE_PREFIX) {
29+
let krate = key[ENV_FEATURE_PREFIX.len()..].to_lowercase();
3030
match krate.as_ref() {
3131
"default" | "macos" | "unix" | "windows" | "selinux" => continue, // common/standard feature names
3232
"nightly" | "test_unimplemented" => continue, // crate-local custom features
3333
"test" => continue, // over-ridden with 'uu_test' to avoid collision with rust core crate 'test'
34-
s if s.starts_with(feature_prefix) => continue, // crate feature sets
34+
s if s.starts_with(FEATURE_PREFIX) => continue, // crate feature sets
3535
_ => {} // util feature name
3636
}
37-
crates.push(krate.to_string());
37+
crates.push(krate);
3838
}
3939
}
4040
crates.sort();
@@ -43,33 +43,23 @@ pub fn main() {
4343
let mut tf = File::create(Path::new(&out_dir).join("test_modules.rs")).unwrap();
4444

4545
mf.write_all(
46-
"type UtilityMap<T> = HashMap<&'static str, (fn(T) -> i32, fn() -> App<'static>)>;\n\
46+
"type UtilityMap<T> = phf::Map<&'static str, (fn(T) -> i32, fn() -> App<'static>)>;\n\
4747
\n\
48-
fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n\
49-
\t#[allow(unused_mut)]\n\
50-
\t#[allow(clippy::let_and_return)]\n\
51-
\tlet mut map = UtilityMap::new();\n\
52-
"
53-
.as_bytes(),
48+
fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n"
49+
.as_bytes(),
5450
)
5551
.unwrap();
5652

57-
for krate in crates {
53+
let mut phf_map = phf_codegen::Map::<&str>::new();
54+
for krate in &crates {
55+
let map_value = format!("({krate}::uumain, {krate}::uu_app)", krate = krate);
5856
match krate.as_ref() {
5957
// 'test' is named uu_test to avoid collision with rust core crate 'test'.
6058
// It can also be invoked by name '[' for the '[ expr ] syntax'.
6159
"uu_test" => {
62-
mf.write_all(
63-
format!(
64-
"\
65-
\tmap.insert(\"test\", ({krate}::uumain, {krate}::uu_app));\n\
66-
\t\tmap.insert(\"[\", ({krate}::uumain, {krate}::uu_app));\n\
67-
",
68-
krate = krate
69-
)
70-
.as_bytes(),
71-
)
72-
.unwrap();
60+
phf_map.entry("test", &map_value);
61+
phf_map.entry("[", &map_value);
62+
7363
tf.write_all(
7464
format!(
7565
"#[path=\"{dir}/test_test.rs\"]\nmod test_test;\n",
@@ -79,35 +69,23 @@ pub fn main() {
7969
)
8070
.unwrap()
8171
}
82-
k if k.starts_with(override_prefix) => {
83-
mf.write_all(
84-
format!(
85-
"\tmap.insert(\"{k}\", ({krate}::uumain, {krate}::uu_app));\n",
86-
k = &krate[override_prefix.len()..],
87-
krate = krate
88-
)
89-
.as_bytes(),
90-
)
91-
.unwrap();
72+
k if k.starts_with(OVERRIDE_PREFIX) => {
73+
phf_map.entry(&k[OVERRIDE_PREFIX.len()..], &map_value);
9274
tf.write_all(
9375
format!(
9476
"#[path=\"{dir}/test_{k}.rs\"]\nmod test_{k};\n",
95-
k = &krate[override_prefix.len()..],
77+
k = &krate[OVERRIDE_PREFIX.len()..],
9678
dir = util_tests_dir,
9779
)
9880
.as_bytes(),
9981
)
10082
.unwrap()
10183
}
10284
"false" | "true" => {
103-
mf.write_all(
104-
format!(
105-
"\tmap.insert(\"{krate}\", (r#{krate}::uumain, r#{krate}::uu_app));\n",
106-
krate = krate
107-
)
108-
.as_bytes(),
109-
)
110-
.unwrap();
85+
phf_map.entry(
86+
krate,
87+
&format!("(r#{krate}::uumain, r#{krate}::uu_app)", krate = krate),
88+
);
11189
tf.write_all(
11290
format!(
11391
"#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
@@ -119,29 +97,25 @@ pub fn main() {
11997
.unwrap()
12098
}
12199
"hashsum" => {
122-
mf.write_all(
123-
format!(
124-
"\
125-
\tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app_custom));\n\
126-
\t\tmap.insert(\"md5sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
127-
\t\tmap.insert(\"sha1sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
128-
\t\tmap.insert(\"sha224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
129-
\t\tmap.insert(\"sha256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
130-
\t\tmap.insert(\"sha384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
131-
\t\tmap.insert(\"sha512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
132-
\t\tmap.insert(\"sha3sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
133-
\t\tmap.insert(\"sha3-224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
134-
\t\tmap.insert(\"sha3-256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
135-
\t\tmap.insert(\"sha3-384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
136-
\t\tmap.insert(\"sha3-512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
137-
\t\tmap.insert(\"shake128sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
138-
\t\tmap.insert(\"shake256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
139-
",
140-
krate = krate
141-
)
142-
.as_bytes(),
143-
)
144-
.unwrap();
100+
phf_map.entry(
101+
krate,
102+
&format!("({krate}::uumain, {krate}::uu_app_custom)", krate = krate),
103+
);
104+
105+
let map_value = format!("({krate}::uumain, {krate}::uu_app_common)", krate = krate);
106+
phf_map.entry("md5sum", &map_value);
107+
phf_map.entry("sha1sum", &map_value);
108+
phf_map.entry("sha224sum", &map_value);
109+
phf_map.entry("sha256sum", &map_value);
110+
phf_map.entry("sha384sum", &map_value);
111+
phf_map.entry("sha512sum", &map_value);
112+
phf_map.entry("sha3sum", &map_value);
113+
phf_map.entry("sha3-224sum", &map_value);
114+
phf_map.entry("sha3-256sum", &map_value);
115+
phf_map.entry("sha3-384sum", &map_value);
116+
phf_map.entry("sha3-512sum", &map_value);
117+
phf_map.entry("shake128sum", &map_value);
118+
phf_map.entry("shake256sum", &map_value);
145119
tf.write_all(
146120
format!(
147121
"#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
@@ -153,14 +127,7 @@ pub fn main() {
153127
.unwrap()
154128
}
155129
_ => {
156-
mf.write_all(
157-
format!(
158-
"\tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app));\n",
159-
krate = krate
160-
)
161-
.as_bytes(),
162-
)
163-
.unwrap();
130+
phf_map.entry(krate, &map_value);
164131
tf.write_all(
165132
format!(
166133
"#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
@@ -173,8 +140,8 @@ pub fn main() {
173140
}
174141
}
175142
}
176-
177-
mf.write_all(b"map\n}\n").unwrap();
143+
write!(mf, "{}", phf_map.build()).unwrap();
144+
mf.write_all(b"\n}\n").unwrap();
178145

179146
mf.flush().unwrap();
180147
tf.flush().unwrap();

src/bin/coreutils.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use clap::{App, Arg};
99
use clap_complete::Shell;
1010
use std::cmp;
11-
use std::collections::hash_map::HashMap;
1211
use std::ffi::OsStr;
1312
use std::ffi::OsString;
1413
use std::io::{self, Write};
@@ -171,7 +170,7 @@ fn gen_completions<T: uucore::Args>(
171170

172171
fn gen_coreutils_app<T: uucore::Args>(util_map: UtilityMap<T>) -> App<'static> {
173172
let mut app = App::new("coreutils");
174-
for (_, (_, sub_app)) in util_map {
173+
for (_, (_, sub_app)) in &util_map {
175174
app = app.subcommand(sub_app());
176175
}
177176
app

src/bin/uudoc.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// file that was distributed with this source code.
55

66
use clap::App;
7-
use std::collections::hash_map::HashMap;
87
use std::ffi::OsString;
98
use std::fs::File;
109
use std::io::{self, Write};
@@ -32,7 +31,7 @@ fn main() -> io::Result<()> {
3231
* [Multi-call binary](multicall.md)\n",
3332
);
3433

35-
let mut utils = utils.iter().collect::<Vec<_>>();
34+
let mut utils = utils.entries().collect::<Vec<_>>();
3635
utils.sort();
3736
for (&name, (_, app)) in utils {
3837
if name == "[" {

0 commit comments

Comments
 (0)