use semver::Version;
use std::ops::RangeInclusive;
pub struct CfgGenerator {
prefix: Option<String>,
range_major: RangeInclusive<u64>,
range_minor: RangeInclusive<u64>,
version: Version,
}
impl CfgGenerator {
pub fn new(version: Version) -> Self {
Self {
range_major: (0..=99),
range_minor: (0..=99),
prefix: None,
version,
}
}
pub fn prefix(mut self, prefix: impl Into<String>) -> Self {
self.prefix = Some(prefix.into());
self
}
pub fn range_major(mut self, range: RangeInclusive<u64>) -> Self {
self.range_major = range;
self
}
pub fn range_minor(mut self, range: RangeInclusive<u64>) -> Self {
self.range_minor = range;
self
}
pub fn build(self) {
self.define_cfg_check_variable(
"qt_version_major".to_string(),
Some(
self.range_major
.clone()
.map(|major| major.to_string())
.collect(),
),
);
self.define_cfg_variable(
"qt_version_major".to_string(),
Some(self.version.major.to_string()),
);
for major in self.range_major.clone() {
self.define_cfg_check_variable(format!("qt_version_at_least_{major}"), None);
for minor in self.range_minor.clone() {
self.define_cfg_check_variable(
format!("qt_version_at_least_{major}_{minor}"),
None,
);
}
}
for major in *self.range_major.start()..=self.version.major {
self.define_cfg_variable(format!("qt_version_at_least_{major}"), None);
}
for minor in *self.range_minor.start()..=self.version.minor {
let major = self.version.major;
self.define_cfg_variable(format!("qt_version_at_least_{major}_{minor}"), None);
}
}
}
impl CfgGenerator {
fn define_cfg_check_variable(&self, key: String, values: Option<Vec<String>>) {
let key = self.key_with_prefix(key);
if let Some(values) = values {
let values = values
.iter()
.map(|value| format!("\"{}\"", value.escape_default()))
.collect::<Vec<_>>()
.join(", ");
println!("cargo::rustc-check-cfg=cfg({key}, values({values}))");
} else {
println!("cargo::rustc-check-cfg=cfg({key})");
}
}
fn define_cfg_variable(&self, key: String, value: Option<String>) {
let key = self.key_with_prefix(key);
if let Some(value) = &value {
println!("cargo::rustc-cfg={key}=\"{}\"", value.escape_default());
} else {
println!("cargo::rustc-cfg={key}");
}
let variable_cargo = format!("CARGO_CFG_{key}");
std::env::set_var(variable_cargo, value.unwrap_or("true".to_string()));
}
fn key_with_prefix(&self, key: String) -> String {
if let Some(prefix) = &self.prefix {
format!("{prefix}{key}")
} else {
key
}
}
}