Skip to content

Commit 0a41631

Browse files
authored
optimize compilation (#23)
1 parent ddfebee commit 0a41631

File tree

14 files changed

+122
-187
lines changed

14 files changed

+122
-187
lines changed

.github/workflows/CI.yml

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,8 @@ jobs:
3232
version: latest
3333
run_install: true
3434
- run: pnpm why caniuse-lite electron-to-chromium node-releases
35+
- run: cargo run -p generate-data
3536
- run: cargo test
36-
37-
lint:
38-
name: lint
39-
runs-on: ubuntu-latest
40-
steps:
41-
- uses: actions/checkout@v3
42-
with:
43-
submodules: true
44-
- uses: actions/cache@v3
45-
with:
46-
path: |
47-
~/.cargo/bin/
48-
~/.cargo/registry/index/
49-
~/.cargo/registry/cache/
50-
~/.cargo/git/db/
51-
target/
52-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}
5337
- run: cargo clippy --all-features
5438
- run: cargo clippy --example inspect
5539
- run: cargo clippy --tests
@@ -62,4 +46,5 @@ jobs:
6246
with:
6347
submodules: true
6448
- run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
49+
- run: cargo run -p generate-data
6550
- run: wasm-pack build --dev --target=web -- --features wasm_bindgen

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@
55
"**/bower_components": true,
66
"**/*.code-search": true,
77
"vendor/**": true
8-
}
8+
},
9+
"rust-analyzer.files.excludeDirs": [
10+
"src/generated"
11+
]
912
}

Cargo.toml

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,7 @@ repository = "https://github.com/browserslist/browserslist-rs"
88
license = "MIT"
99
keywords = ["web", "javascript"]
1010
categories = ["web-programming", "config"]
11-
include = [
12-
"**/*.rs",
13-
"Cargo.toml",
14-
"vendor/caniuse/fulldata-json/data-2.0.json",
15-
"vendor/canisue/features-json/*.json",
16-
"vendor/caniuse/region-usage-json/*.json",
17-
"vendor/electron-to-chromium/versions.json",
18-
"vendor/node-releases/data/**/*.json",
19-
]
11+
include = ["**/*.rs", "Cargo.toml", "src/generated/**/*.json"]
2012

2113
[lib]
2214
name = "browserslist"
@@ -39,30 +31,24 @@ chrono = { version = "0.4.31", features = [
3931
"clock",
4032
"oldtime",
4133
], default-features = false } # disable wasmbind by default
42-
either = "1.9"
43-
indexmap = { version = "2.1", features = ["serde"] }
44-
itertools = "0.12"
34+
either = "1.12"
35+
indexmap = { version = "2.2", features = ["serde"] }
36+
itertools = "0.13"
4537
nom = "7.1"
4638
once_cell = "1.19"
4739
serde = { version = "1.0", features = ["derive"] }
4840
serde_json = "1.0"
49-
string_cache = "0.8"
5041
thiserror = "1.0"
5142

5243
[dev-dependencies]
5344
clap = { version = "4.4", features = ["derive"] }
5445
test-case = "3.3"
5546

56-
[build-dependencies]
57-
anyhow = "1.0"
58-
indexmap = { version = "2.1", features = ["serde"] }
59-
quote = "1.0"
60-
serde = { version = "1.0", features = ["derive"] }
61-
serde_json = "1.0"
62-
string_cache_codegen = "0.5.2"
63-
6447
[target.'cfg(target_arch = "wasm32")'.dependencies]
6548
getrandom = { version = "0.2", optional = true }
6649
js-sys = { version = "0.3", optional = true }
6750
serde-wasm-bindgen = { version = "0.4", optional = true }
6851
wasm-bindgen = { version = "0.2", optional = true }
52+
53+
[workspace]
54+
members = [".", "generate-data"]

generate-data/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "generate-data"
3+
version = "0.1.0"
4+
authors = ["Pig Fang <g-plane@hotmail.com>"]
5+
edition = "2021"
6+
publish = false
7+
8+
[dependencies]
9+
anyhow = "1.0"
10+
indexmap = { version = "2.1", features = ["serde"] }
11+
quote = "1.0"
12+
serde = { version = "1.0", features = ["derive"] }
13+
serde_json = "1.0"

build.rs renamed to generate-data/src/main.rs

Lines changed: 45 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ use quote::quote;
44
use serde::{Deserialize, Serialize};
55
use std::{
66
collections::{BTreeMap, HashMap},
7-
env, fs, io,
7+
fs, io,
88
path::Path,
99
};
1010

11+
const OUT_DIR: &str = "src/generated";
12+
1113
fn encode_browser_name(name: &str) -> u8 {
1214
match name {
1315
"ie" => 1,
@@ -58,7 +60,6 @@ struct Feature {
5860
}
5961

6062
fn main() -> Result<()> {
61-
generate_browser_names_cache()?;
6263
build_electron_to_chromium()?;
6364
build_node_versions()?;
6465
build_node_release_schedule()?;
@@ -68,30 +69,12 @@ fn main() -> Result<()> {
6869
Ok(())
6970
}
7071

71-
fn generate_browser_names_cache() -> Result<()> {
72-
string_cache_codegen::AtomType::new(
73-
"data::browser_name::BrowserNameAtom",
74-
"browser_name_atom!",
75-
)
76-
.atoms(&[
77-
"ie", "edge", "firefox", "chrome", "safari", "opera", "ios_saf", "op_mini", "android",
78-
"bb", "op_mob", "and_chr", "and_ff", "ie_mob", "and_uc", "samsung", "and_qq", "baidu",
79-
"kaios",
80-
])
81-
.write_to_file(&Path::new(&env::var("OUT_DIR")?).join("browser_name_atom.rs"))?;
82-
83-
Ok(())
84-
}
85-
8672
fn build_electron_to_chromium() -> Result<()> {
87-
println!("cargo:rerun-if-changed=vendor/electron-to-chromium/versions.json");
88-
89-
let path = format!("{}/electron-to-chromium.rs", env::var("OUT_DIR")?);
73+
let path = format!("{OUT_DIR}/electron-to-chromium.rs");
9074

91-
let mut data = serde_json::from_slice::<BTreeMap<String, String>>(&fs::read(format!(
92-
"{}/vendor/electron-to-chromium/versions.json",
93-
env::var("CARGO_MANIFEST_DIR")?
94-
))?)?
75+
let mut data = serde_json::from_slice::<BTreeMap<String, String>>(&fs::read(
76+
"vendor/electron-to-chromium/versions.json",
77+
)?)?
9578
.into_iter()
9679
.map(|(electron_version, chromium_version)| {
9780
(electron_version.parse::<f32>().unwrap(), chromium_version)
@@ -123,14 +106,10 @@ fn build_node_versions() -> Result<()> {
123106
version: String,
124107
}
125108

126-
println!("cargo:rerun-if-changed=vendor/node-releases/data/processed/envs.json");
127-
128-
let path = format!("{}/node-versions.rs", env::var("OUT_DIR")?);
109+
let path = format!("{OUT_DIR}/node-versions.rs");
129110

130-
let releases: Vec<NodeRelease> = serde_json::from_slice(&fs::read(format!(
131-
"{}/vendor/node-releases/data/processed/envs.json",
132-
env::var("CARGO_MANIFEST_DIR")?
133-
))?)?;
111+
let releases: Vec<NodeRelease> =
112+
serde_json::from_slice(&fs::read("vendor/node-releases/data/processed/envs.json")?)?;
134113

135114
let versions = releases.into_iter().map(|release| release.version);
136115
fs::write(
@@ -145,22 +124,17 @@ fn build_node_versions() -> Result<()> {
145124
}
146125

147126
fn build_node_release_schedule() -> Result<()> {
148-
println!(
149-
"cargo:rerun-if-changed=vendor/node-releases/data/release-schedule/release-schedule.json"
150-
);
151-
152127
#[derive(Deserialize)]
153128
struct NodeRelease {
154129
start: String,
155130
end: String,
156131
}
157132

158-
let path = format!("{}/node-release-schedule.rs", env::var("OUT_DIR")?);
133+
let path = format!("{OUT_DIR}/node-release-schedule.rs");
159134

160-
let schedule: HashMap<String, NodeRelease> = serde_json::from_slice(&fs::read(format!(
161-
"{}/vendor/node-releases/data/release-schedule/release-schedule.json",
162-
env::var("CARGO_MANIFEST_DIR")?
163-
))?)?;
135+
let schedule: HashMap<String, NodeRelease> = serde_json::from_slice(&fs::read(
136+
"vendor/node-releases/data/release-schedule/release-schedule.json",
137+
)?)?;
164138
let cap = schedule.len();
165139
let versions = schedule
166140
.into_iter()
@@ -185,12 +159,10 @@ fn build_node_release_schedule() -> Result<()> {
185159
}
186160

187161
fn build_caniuse_global() -> Result<()> {
188-
let out_dir = env::var("OUT_DIR")?;
189-
190162
let data = parse_caniuse_global()?;
191163

192164
fs::write(
193-
format!("{}/caniuse-browsers.rs", &out_dir),
165+
format!("{OUT_DIR}/caniuse-browsers.rs"),
194166
{
195167
let map_cap = data.agents.len();
196168
let browser_stat = data.agents.iter().map(|(name, agent)| {
@@ -211,14 +183,13 @@ fn build_caniuse_global() -> Result<()> {
211183
}
212184
});
213185
quote! {
214-
map.insert(BrowserNameAtom::from(#name), BrowserStat {
215-
name: BrowserNameAtom::from(#name),
186+
map.insert(#name, BrowserStat {
187+
name: #name,
216188
version_list: vec![#(#detail),*],
217189
});
218190
}
219191
});
220192
quote! {{
221-
use ahash::AHashMap;
222193
let mut map = AHashMap::with_capacity(#map_cap);
223194
#(#browser_stat)*
224195
map
@@ -235,7 +206,7 @@ fn build_caniuse_global() -> Result<()> {
235206
(
236207
usage,
237208
quote! {
238-
(BrowserNameAtom::from(#name), #version, #usage)
209+
(#name, #version, #usage)
239210
},
240211
)
241212
})
@@ -244,20 +215,20 @@ fn build_caniuse_global() -> Result<()> {
244215
global_usage.sort_unstable_by(|(a, _), (b, _)| b.partial_cmp(a).unwrap());
245216
let push_usage = global_usage.into_iter().map(|(_, tokens)| tokens);
246217
fs::write(
247-
format!("{}/caniuse-global-usage.rs", &out_dir),
218+
format!("{OUT_DIR}/caniuse-global-usage.rs"),
248219
quote! {
249220
vec![#(#push_usage),*]
250221
}
251222
.to_string(),
252223
)?;
253224

254-
let features_dir = format!("{}/features", &out_dir);
225+
let features_dir = format!("{OUT_DIR}/features");
255226
if matches!(fs::File::open(&features_dir), Err(e) if e.kind() == io::ErrorKind::NotFound) {
256227
fs::create_dir(&features_dir)?;
257228
}
258229
for (name, feature) in &data.data {
259230
fs::write(
260-
format!("{}/{}.json", &features_dir, name),
231+
format!("{features_dir}/{name}.json"),
261232
serde_json::to_string(
262233
&feature
263234
.stats
@@ -290,15 +261,18 @@ fn build_caniuse_global() -> Result<()> {
290261
use indexmap::IndexMap;
291262
use once_cell::sync::Lazy;
292263
use serde_json::from_str;
293-
use crate::data::browser_name::BrowserNameAtom;
264+
use crate::data::decode_browser_name;
265+
266+
type Stat = Lazy<AHashMap<&'static str, IndexMap<&'static str, u8>>>;
267+
type Json = AHashMap::<u8, IndexMap<&'static str, u8>>;
294268

295269
match name {
296270
#( #features => {
297-
static STAT: Lazy<AHashMap<BrowserNameAtom, IndexMap<&'static str, u8>>> = Lazy::new(|| {
298-
from_str::<AHashMap::<u8, IndexMap<&'static str, u8>>>(include_str!(concat!(env!("OUT_DIR"), "/features/", #features, ".json")))
271+
static STAT: Stat = Lazy::new(|| {
272+
from_str::<Json>(include_str!(concat!("features/", #features, ".json")))
299273
.unwrap()
300274
.into_iter()
301-
.map(|(browser, versions)| (crate::data::browser_name::decode_browser_name(browser), versions))
275+
.map(|(browser, versions)| (decode_browser_name(browser), versions))
302276
.collect()
303277
});
304278
Some(&*STAT)
@@ -307,20 +281,17 @@ fn build_caniuse_global() -> Result<()> {
307281
}
308282
}};
309283
fs::write(
310-
format!("{}/caniuse-feature-matching.rs", &out_dir),
284+
format!("{OUT_DIR}/caniuse-feature-matching.rs"),
311285
tokens.to_string(),
312286
)?;
313287

314288
Ok(())
315289
}
316290

317291
fn parse_caniuse_global() -> Result<Caniuse> {
318-
println!("cargo:rerun-if-changed=vendor/caniuse/fulldata-json/data-2.0.json");
319-
320-
Ok(serde_json::from_slice(&fs::read(format!(
321-
"{}/vendor/caniuse/fulldata-json/data-2.0.json",
322-
env::var("CARGO_MANIFEST_DIR")?
323-
))?)?)
292+
Ok(serde_json::from_slice(&fs::read(
293+
"vendor/caniuse/fulldata-json/data-2.0.json",
294+
)?)?)
324295
}
325296

326297
fn build_caniuse_region() -> Result<()> {
@@ -329,25 +300,13 @@ fn build_caniuse_region() -> Result<()> {
329300
data: HashMap<String, HashMap<String, Option<f32>>>,
330301
}
331302

332-
let files = fs::read_dir(format!(
333-
"{}/vendor/caniuse/region-usage-json",
334-
env::var("CARGO_MANIFEST_DIR")?
335-
))?
336-
.map(|entry| entry.map_err(anyhow::Error::from))
337-
.collect::<Result<Vec<_>>>()?;
338-
339-
files.iter().for_each(|entry| {
340-
println!(
341-
"cargo:rerun-if-changed=vendor/caniuse/region-usage-json/{}",
342-
entry.file_name().into_string().unwrap()
343-
)
344-
});
345-
346-
let out_dir = env::var("OUT_DIR")?;
303+
let files = fs::read_dir("vendor/caniuse/region-usage-json")?
304+
.map(|entry| entry.map_err(anyhow::Error::from))
305+
.collect::<Result<Vec<_>>>()?;
347306

348307
let Caniuse { agents, .. } = parse_caniuse_global()?;
349308

350-
let region_dir = format!("{}/region", &out_dir);
309+
let region_dir = format!("{OUT_DIR}/region");
351310
if matches!(fs::File::open(&region_dir), Err(e) if e.kind() == io::ErrorKind::NotFound) {
352311
fs::create_dir(&region_dir)?;
353312
}
@@ -370,7 +329,7 @@ fn build_caniuse_region() -> Result<()> {
370329
.collect::<Vec<_>>();
371330
usage.sort_unstable_by(|(_, _, a), (_, _, b)| b.partial_cmp(a).unwrap());
372331
fs::write(
373-
format!("{}/region/{}", &out_dir, file.file_name().to_str().unwrap()),
332+
format!("{OUT_DIR}/region/{}", file.file_name().to_str().unwrap()),
374333
serde_json::to_string(&usage)?,
375334
)?;
376335
}
@@ -389,15 +348,18 @@ fn build_caniuse_region() -> Result<()> {
389348
let tokens = quote! {{
390349
use once_cell::sync::Lazy;
391350
use serde_json::from_str;
392-
use crate::data::browser_name::BrowserNameAtom;
351+
use crate::data::decode_browser_name;
352+
353+
type Usage = Lazy<Vec<(&'static str, &'static str, f32)>>;
354+
type Json = Vec<(u8, &'static str, f32)>;
393355

394356
match region {
395357
#( #regions => {
396-
static USAGE: Lazy<Vec<(BrowserNameAtom, &'static str, f32)>> = Lazy::new(|| {
397-
from_str::<Vec<(u8, &'static str, f32)>>(include_str!(concat!(env!("OUT_DIR"), "/region/", #regions, ".json")))
358+
static USAGE: Usage = Lazy::new(|| {
359+
from_str::<Json>(include_str!(concat!("region/", #regions, ".json")))
398360
.unwrap()
399361
.into_iter()
400-
.map(|(browser, version, usage)| (crate::data::browser_name::decode_browser_name(browser), version, usage))
362+
.map(|(browser, version, usage)| (decode_browser_name(browser), version, usage))
401363
.collect()
402364
});
403365
Some(&*USAGE)
@@ -406,7 +368,7 @@ fn build_caniuse_region() -> Result<()> {
406368
}
407369
}};
408370
fs::write(
409-
format!("{}/caniuse-region-matching.rs", &out_dir),
371+
format!("{OUT_DIR}/caniuse-region-matching.rs"),
410372
tokens.to_string(),
411373
)?;
412374

0 commit comments

Comments
 (0)