Skip to content

Commit

Permalink
avoid parsing JSON at run-time
Browse files Browse the repository at this point in the history
  • Loading branch information
g-plane committed Jan 26, 2024
1 parent 917e6d2 commit ebc30da
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 123 deletions.
130 changes: 87 additions & 43 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn generate_browser_names_cache() -> Result<()> {
fn build_electron_to_chromium() -> Result<()> {
println!("cargo:rerun-if-changed=vendor/electron-to-chromium/versions.json");

let path = format!("{}/electron-to-chromium.json", env::var("OUT_DIR")?);
let path = format!("{}/electron-to-chromium.rs", env::var("OUT_DIR")?);

let mut data = serde_json::from_slice::<BTreeMap<String, String>>(&fs::read(format!(
"{}/vendor/electron-to-chromium/versions.json",
Expand All @@ -98,8 +98,21 @@ fn build_electron_to_chromium() -> Result<()> {
})
.collect::<Vec<_>>();
data.sort_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap());
let data = data
.into_iter()
.map(|(electron_version, chromium_version)| {
quote! {
(#electron_version, #chromium_version)
}
});

fs::write(path, serde_json::to_string(&data)?)?;
fs::write(
path,
quote! {{
vec![#(#data),*]
}}
.to_string(),
)?;

Ok(())
}
Expand All @@ -112,21 +125,20 @@ fn build_node_versions() -> Result<()> {

println!("cargo:rerun-if-changed=vendor/node-releases/data/processed/envs.json");

let path = format!("{}/node-versions.json", env::var("OUT_DIR")?);
let path = format!("{}/node-versions.rs", env::var("OUT_DIR")?);

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

let versions = releases.into_iter().map(|release| release.version);
fs::write(
path,
serde_json::to_string(
&releases
.into_iter()
.map(|release| release.version)
.collect::<Vec<_>>(),
)?,
quote! {{
vec![#(#versions),*]
}}
.to_string(),
)?;

Ok(())
Expand All @@ -143,26 +155,30 @@ fn build_node_release_schedule() -> Result<()> {
end: String,
}

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

let schedule: HashMap<String, NodeRelease> = serde_json::from_slice(&fs::read(format!(
"{}/vendor/node-releases/data/release-schedule/release-schedule.json",
env::var("CARGO_MANIFEST_DIR")?
))?)?;
let cap = schedule.len();
let versions = schedule
.into_iter()
.map(|(version, NodeRelease { start, end })| {
let version = version.trim_start_matches('v');
quote! {
map.insert(#version, (#start, #end));
}
});

fs::write(
path,
serde_json::to_string(
&schedule
.into_iter()
.map(|(version, release)| {
(
version.trim_start_matches('v').to_owned(),
(release.start, release.end),
)
})
.collect::<HashMap<_, _>>(),
)?,
quote! {{
let mut map = ahash::AHashMap::with_capacity(#cap);
#(#versions)*
map
}}
.to_string(),
)?;

Ok(())
Expand All @@ -179,38 +195,66 @@ fn build_caniuse_global() -> Result<()> {

let data = parse_caniuse_global()?;

let browsers = data
.agents
.iter()
.map(|(name, agent)| {
(
name,
BrowserStat {
name: name.to_string(),
version_list: agent.version_list.clone(),
},
)
})
.collect::<HashMap<_, _>>();
fs::write(
format!("{}/caniuse-browsers.json", &out_dir),
serde_json::to_string(&browsers)?,
format!("{}/caniuse-browsers.rs", &out_dir),
{
let map_cap = data.agents.len();
let browser_stat = data.agents.iter().map(|(name, agent)| {
let detail = agent.version_list.iter().map(|version| {
let ver = &version.version;
let global_usage = version.global_usage;
let release_date = if let Some(release_date) = version.release_date {
quote! { Some(#release_date) }
} else {
quote! { None }
};
quote! {
VersionDetail {
version: #ver,
global_usage: #global_usage,
release_date: #release_date,
}
}
});
quote! {
map.insert(BrowserNameAtom::from(#name), BrowserStat {
name: BrowserNameAtom::from(#name),
version_list: vec![#(#detail),*],
});
}
});
quote! {{
use ahash::AHashMap;
let mut map = AHashMap::with_capacity(#map_cap);
#(#browser_stat)*
map
}}
}
.to_string(),
)?;

let mut global_usage = data
.agents
.iter()
.flat_map(|(name, agent)| {
agent
.usage_global
.iter()
.map(|(version, usage)| (encode_browser_name(name), version.clone(), usage))
agent.usage_global.iter().map(move |(version, usage)| {
(
usage,
quote! {
(BrowserNameAtom::from(#name), #version, #usage)
},
)
})
})
.collect::<Vec<_>>();
global_usage.sort_unstable_by(|(_, _, a), (_, _, b)| b.partial_cmp(a).unwrap());
global_usage.sort_unstable_by(|(a, _), (b, _)| b.partial_cmp(a).unwrap());
let push_usage = global_usage.into_iter().map(|(_, tokens)| tokens);
fs::write(
format!("{}/caniuse-global-usage.json", &out_dir),
serde_json::to_string(&global_usage)?,
format!("{}/caniuse-global-usage.rs", &out_dir),
quote! {
vec![#(#push_usage),*]
}
.to_string(),
)?;

let features_dir = format!("{}/features", &out_dir);
Expand Down
40 changes: 10 additions & 30 deletions src/data/caniuse.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::browser_name::BrowserNameAtom;
use ahash::AHashMap;
use once_cell::sync::Lazy;
use serde::Deserialize;
use std::borrow::Cow;

pub(crate) mod features;
Expand All @@ -10,45 +9,26 @@ pub(crate) mod region;
pub const ANDROID_EVERGREEN_FIRST: f32 = 37.0;
pub const OP_MOB_BLINK_FIRST: u32 = 14;

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug)]
pub struct BrowserStat {
name: BrowserNameAtom,
pub version_list: Vec<VersionDetail>,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug)]
pub struct VersionDetail {
pub version: String,
pub version: &'static str,
pub global_usage: f32,
pub release_date: Option<i64>,
}

pub type CaniuseData = AHashMap<BrowserNameAtom, BrowserStat>;

pub static CANIUSE_BROWSERS: Lazy<CaniuseData> = Lazy::new(|| {
serde_json::from_str(include_str!(concat!(
env!("OUT_DIR"),
"/caniuse-browsers.json"
)))
.unwrap()
});
pub static CANIUSE_BROWSERS: Lazy<CaniuseData> =
Lazy::new(|| include!(concat!(env!("OUT_DIR"), "/caniuse-browsers.rs")));

pub static CANIUSE_GLOBAL_USAGE: Lazy<Vec<(BrowserNameAtom, String, f32)>> = Lazy::new(|| {
serde_json::from_str::<Vec<(u8, String, f32)>>(include_str!(concat!(
env!("OUT_DIR"),
"/caniuse-global-usage.json"
)))
.unwrap()
.into_iter()
.map(|(browser, version, usage)| {
(
super::browser_name::decode_browser_name(browser),
version,
usage,
)
})
.collect()
});
pub static CANIUSE_GLOBAL_USAGE: Lazy<Vec<(BrowserNameAtom, &'static str, f32)>> =
Lazy::new(|| include!(concat!(env!("OUT_DIR"), "/caniuse-global-usage.rs")));

pub static BROWSER_VERSION_ALIASES: Lazy<
AHashMap<BrowserNameAtom, AHashMap<&'static str, &'static str>>,
Expand All @@ -63,7 +43,7 @@ pub static BROWSER_VERSION_ALIASES: Lazy<
version
.version
.split_once('-')
.map(|(bottom, top)| (bottom, top, version.version.as_str()))
.map(|(bottom, top)| (bottom, top, version.version))
})
.fold(
AHashMap::<&str, &str>::new(),
Expand Down Expand Up @@ -96,7 +76,7 @@ static ANDROID_TO_DESKTOP: Lazy<BrowserStat> = Lazy::new(|| {
.version_list
.into_iter()
.filter(|version| {
let version = &version.version;
let version = version.version;
version.starts_with("2.")
|| version.starts_with("3.")
|| version.starts_with("4.")
Expand Down Expand Up @@ -207,7 +187,7 @@ pub(crate) fn normalize_version<'a>(
{
Some(version)
} else if stat.version_list.len() == 1 {
stat.version_list.first().map(|s| s.version.as_str())
stat.version_list.first().map(|s| s.version)
} else {
None
}
Expand Down
9 changes: 2 additions & 7 deletions src/data/electron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ use nom::{
};
use once_cell::sync::Lazy;

pub static ELECTRON_VERSIONS: Lazy<Vec<(f32, String)>> = Lazy::new(|| {
serde_json::from_str(include_str!(concat!(
env!("OUT_DIR"),
"/electron-to-chromium.json"
)))
.unwrap()
});
pub static ELECTRON_VERSIONS: Lazy<Vec<(f32, &'static str)>> =
Lazy::new(|| include!(concat!(env!("OUT_DIR"), "/electron-to-chromium.rs")));

pub(crate) fn parse_version(version: &str) -> Result<f32, Error> {
all_consuming(terminated(float, opt(pair(char('.'), u16))))(version)
Expand Down
49 changes: 20 additions & 29 deletions src/data/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,29 @@ use ahash::AHashMap;
use chrono::{NaiveDate, NaiveDateTime};
use once_cell::sync::Lazy;

pub static NODE_VERSIONS: Lazy<Vec<String>> = Lazy::new(|| {
serde_json::from_str(include_str!(concat!(
env!("OUT_DIR"),
"/node-versions.json"
)))
.unwrap()
});
pub static NODE_VERSIONS: Lazy<Vec<&'static str>> =
Lazy::new(|| include!(concat!(env!("OUT_DIR"), "/node-versions.rs")));

pub static RELEASE_SCHEDULE: Lazy<AHashMap<String, (NaiveDateTime, NaiveDateTime)>> =
pub static RELEASE_SCHEDULE: Lazy<AHashMap<&'static str, (NaiveDateTime, NaiveDateTime)>> =
Lazy::new(|| {
let date_format = "%Y-%m-%d";

serde_json::from_str::<AHashMap<String, (String, String)>>(include_str!(concat!(
env!("OUT_DIR"),
"/node-release-schedule.json"
)))
.unwrap()
.into_iter()
.map(|(version, (start, end))| {
(
version,
include!(concat!(env!("OUT_DIR"), "/node-release-schedule.rs"))
.into_iter()
.map(|(version, (start, end))| {
(
NaiveDate::parse_from_str(&start, date_format)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap(),
NaiveDate::parse_from_str(&end, date_format)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap(),
),
)
})
.collect()
version,
(
NaiveDate::parse_from_str(&start, date_format)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap(),
NaiveDate::parse_from_str(&end, date_format)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap(),
),
)
})
.collect()
});
2 changes: 1 addition & 1 deletion src/queries/cover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(super) fn cover(coverage: f32) -> QueryResult {
if total >= coverage || *usage == 0.0 {
ControlFlow::Break((distribs, total))
} else {
distribs.push(Distrib::new(name, version));
distribs.push(Distrib::new(name, *version));
ControlFlow::Continue((distribs, total + usage))
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/queries/electron_accurate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub(super) fn electron_accurate(version: &str) -> QueryResult {
let distribs = ELECTRON_VERSIONS
.iter()
.find(|(electron_version, _)| *electron_version == version)
.map(|(_, chromium_version)| vec![Distrib::new("chrome", chromium_version)])
.map(|(_, chromium_version)| vec![Distrib::new("chrome", *chromium_version)])
.ok_or_else(|| Error::UnknownElectronVersion(version_str.to_string()))?;
Ok(distribs)
}
Expand Down
2 changes: 1 addition & 1 deletion src/queries/electron_bounded_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub(super) fn electron_bounded_range(from: &str, to: &str) -> QueryResult {
let distribs = ELECTRON_VERSIONS
.iter()
.filter(|(version, _)| from <= *version && *version <= to)
.map(|(_, version)| Distrib::new("chrome", version))
.map(|(_, version)| Distrib::new("chrome", *version))
.collect();
Ok(distribs)
}
Expand Down
2 changes: 1 addition & 1 deletion src/queries/electron_unbounded_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub(super) fn electron_unbounded_range(comparator: Comparator, version: &str) ->
Comparator::GreaterOrEqual => *electron_version >= version,
Comparator::LessOrEqual => *electron_version <= version,
})
.map(|(_, chromium_version)| Distrib::new("chrome", chromium_version))
.map(|(_, chromium_version)| Distrib::new("chrome", *chromium_version))
.collect();
Ok(distribs)
}
Expand Down
2 changes: 1 addition & 1 deletion src/queries/last_n_electron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub(super) fn last_n_electron(count: usize) -> QueryResult {
.iter()
.rev()
.take(count)
.map(|(_, version)| Distrib::new("chrome", version))
.map(|(_, version)| Distrib::new("chrome", *version))
.collect();
Ok(distribs)
}
Expand Down
Loading

0 comments on commit ebc30da

Please sign in to comment.