1use semver::Version;
7use std::ops::RangeInclusive;
8
9pub struct CfgGenerator {
11 prefix: Option<String>,
12 range_major: RangeInclusive<u64>,
13 range_minor: RangeInclusive<u64>,
14 version: Version,
15}
16
17impl CfgGenerator {
18 pub fn new(version: Version) -> Self {
20 Self {
21 range_major: (0..=99),
22 range_minor: (0..=99),
23 prefix: None,
24 version,
25 }
26 }
27
28 pub fn prefix(mut self, prefix: impl Into<String>) -> Self {
30 self.prefix = Some(prefix.into());
31 self
32 }
33
34 pub fn range_major(mut self, range: RangeInclusive<u64>) -> Self {
36 self.range_major = range;
37 self
38 }
39
40 pub fn range_minor(mut self, range: RangeInclusive<u64>) -> Self {
42 self.range_minor = range;
43 self
44 }
45
46 pub fn build(self) {
48 self.define_cfg_check_variable(
50 "qt_version_major".to_string(),
51 Some(
52 self.range_major
53 .clone()
54 .map(|major| major.to_string())
55 .collect(),
56 ),
57 );
58 self.define_cfg_variable(
59 "qt_version_major".to_string(),
60 Some(self.version.major.to_string()),
61 );
62
63 for major in self.range_major.clone() {
65 self.define_cfg_check_variable(format!("qt_version_at_least_{major}"), None);
66
67 for minor in self.range_minor.clone() {
68 self.define_cfg_check_variable(
69 format!("qt_version_at_least_{major}_{minor}"),
70 None,
71 );
72 }
73 }
74
75 for major in *self.range_major.start()..=self.version.major {
77 self.define_cfg_variable(format!("qt_version_at_least_{major}"), None);
78 }
79
80 for minor in *self.range_minor.start()..=self.version.minor {
82 let major = self.version.major;
83 self.define_cfg_variable(format!("qt_version_at_least_{major}_{minor}"), None);
84 }
85 }
86}
87
88impl CfgGenerator {
89 fn define_cfg_check_variable(&self, key: String, values: Option<Vec<String>>) {
90 let key = self.key_with_prefix(key);
91
92 if let Some(values) = values {
93 let values = values
94 .iter()
95 .map(|value| format!("\"{}\"", value.escape_default()))
97 .collect::<Vec<_>>()
98 .join(", ");
99
100 println!("cargo::rustc-check-cfg=cfg({key}, values({values}))");
101 } else {
102 println!("cargo::rustc-check-cfg=cfg({key})");
103 }
104 }
105
106 fn define_cfg_variable(&self, key: String, value: Option<String>) {
107 let key = self.key_with_prefix(key);
108
109 if let Some(value) = &value {
110 println!("cargo::rustc-cfg={key}=\"{}\"", value.escape_default());
111 } else {
112 println!("cargo::rustc-cfg={key}");
113 }
114
115 let variable_cargo = format!("CARGO_CFG_{key}");
116 std::env::set_var(variable_cargo, value.unwrap_or("true".to_string()));
117 }
118
119 fn key_with_prefix(&self, key: String) -> String {
120 if let Some(prefix) = &self.prefix {
121 format!("{prefix}{key}")
122 } else {
123 key
124 }
125 }
126}