Skip to content

Commit f8179c5

Browse files
committed
Add CheckCfg/ExpectedValues to cargo-platform
1 parent bed213e commit f8179c5

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//! check-cfg
2+
3+
use std::collections::{HashMap, HashSet};
4+
5+
/// Check Config (aka `--print=check-cfg` representation)
6+
#[derive(Debug, Default, Clone)]
7+
pub struct CheckCfg {
8+
/// Is `--check-cfg` activated
9+
pub exhaustive: bool,
10+
/// List of expected cfgs
11+
pub expecteds: HashMap<String, ExpectedValues>,
12+
}
13+
14+
/// List of expected check-cfg values
15+
#[derive(Debug, Clone, PartialEq, Eq)]
16+
pub enum ExpectedValues {
17+
/// List of expected values
18+
Some(HashSet<Option<String>>),
19+
/// All values expected
20+
Any,
21+
}
22+
23+
impl CheckCfg {
24+
/// Process an output line
25+
pub fn process_line(&mut self, line: &str) {
26+
if line == "any()=any()" || line == "any()" {
27+
self.exhaustive = false;
28+
return;
29+
}
30+
31+
let mut value: HashSet<Option<String>> = HashSet::default();
32+
let mut value_any_specified = false;
33+
let name: String;
34+
35+
if let Some((n, val)) = line.split_once('=') {
36+
name = n.to_string();
37+
38+
if val == "any()" {
39+
value_any_specified = true;
40+
} else if val.is_empty() {
41+
// no value to add
42+
// strip "" around the value, e.g. "linux" -> linux
43+
} else if let Some(val) = val.strip_prefix('"').map(|v| v.strip_suffix('"')).flatten() {
44+
value.insert(Some(val.to_string()));
45+
} else {
46+
// missing quotes and non-empty, ignore
47+
return;
48+
}
49+
} else {
50+
name = line.to_string();
51+
value.insert(None);
52+
}
53+
54+
self.expecteds
55+
.entry(name)
56+
.and_modify(|v| match v {
57+
ExpectedValues::Some(v) if !value_any_specified => {
58+
v.extend(value.clone());
59+
}
60+
ExpectedValues::Some(_) => *v = ExpectedValues::Any,
61+
ExpectedValues::Any => {}
62+
})
63+
.or_insert_with(|| {
64+
if value_any_specified {
65+
ExpectedValues::Any
66+
} else {
67+
ExpectedValues::Some(value)
68+
}
69+
});
70+
}
71+
}

crates/cargo-platform/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ use std::fmt;
1212
use std::str::FromStr;
1313

1414
mod cfg;
15+
mod check_cfg;
1516
mod error;
1617

1718
pub use cfg::{Cfg, CfgExpr};
19+
pub use check_cfg::{CheckCfg, ExpectedValues};
1820
pub use error::{ParseError, ParseErrorKind};
1921

2022
/// Platform definition.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use cargo_platform::{CheckCfg, ExpectedValues};
2+
use std::collections::HashSet;
3+
4+
#[test]
5+
fn check_cfg_none() {
6+
let mut check_cfg = CheckCfg::default();
7+
8+
check_cfg.process_line("cfg_a");
9+
assert_eq!(
10+
*check_cfg.expecteds.get("cfg_a").unwrap(),
11+
ExpectedValues::Some(HashSet::from([None]))
12+
);
13+
}
14+
15+
#[test]
16+
fn check_cfg_empty() {
17+
let mut check_cfg = CheckCfg::default();
18+
19+
check_cfg.process_line("cfg_b=");
20+
assert_eq!(
21+
*check_cfg.expecteds.get("cfg_b").unwrap(),
22+
ExpectedValues::Some(HashSet::from([]))
23+
);
24+
}
25+
26+
#[test]
27+
fn check_cfg_any() {
28+
let mut check_cfg = CheckCfg::default();
29+
30+
check_cfg.process_line("cfg_c=any()");
31+
assert_eq!(
32+
*check_cfg.expecteds.get("cfg_c").unwrap(),
33+
ExpectedValues::Any
34+
);
35+
36+
check_cfg.process_line("cfg_c");
37+
assert_eq!(
38+
*check_cfg.expecteds.get("cfg_c").unwrap(),
39+
ExpectedValues::Any
40+
);
41+
}
42+
43+
#[test]
44+
fn check_cfg_value() {
45+
let mut check_cfg = CheckCfg::default();
46+
47+
check_cfg.process_line("cfg_d=\"test\"");
48+
assert_eq!(
49+
*check_cfg.expecteds.get("cfg_d").unwrap(),
50+
ExpectedValues::Some(HashSet::from([Some("test".to_string())]))
51+
);
52+
53+
check_cfg.process_line("cfg_d=\"tmp\"");
54+
assert_eq!(
55+
*check_cfg.expecteds.get("cfg_d").unwrap(),
56+
ExpectedValues::Some(HashSet::from([
57+
Some("test".to_string()),
58+
Some("tmp".to_string())
59+
]))
60+
);
61+
}
62+
63+
#[test]
64+
fn check_cfg_weird() {
65+
let mut check_cfg = CheckCfg::default();
66+
67+
check_cfg.process_line("cfg_e=\"double_quote\"\"");
68+
assert_eq!(
69+
*check_cfg.expecteds.get("cfg_e").unwrap(),
70+
ExpectedValues::Some(HashSet::from([Some("double_quote\"".to_string())]))
71+
);
72+
73+
check_cfg.process_line("cfg_e=any()"); // this shouldn't be possible but better handle this
74+
// correctly anyway
75+
assert_eq!(
76+
*check_cfg.expecteds.get("cfg_e").unwrap(),
77+
ExpectedValues::Any
78+
);
79+
}

0 commit comments

Comments
 (0)