Skip to main content

sim_config/
keys.rs

1//! Canonical config field identity helpers.
2
3use sim_kernel::Expr;
4
5/// Returns the canonical unqualified config field name represented by `key`.
6///
7/// Config tables accept bare symbol keys and string keys for unqualified field
8/// names. Qualified symbols and other expression keys do not spell a config
9/// field name.
10pub fn config_field_name(key: &Expr) -> Option<&str> {
11    match key {
12        Expr::Symbol(symbol) if symbol.namespace.is_none() => Some(symbol.name.as_ref()),
13        Expr::String(text) => Some(text),
14        _ => None,
15    }
16}
17
18/// Returns true when two keys identify the same config field.
19///
20/// Unqualified symbol keys and string keys compare by their canonical field
21/// names. Keys outside that config-field identity fall back to exact expression
22/// equality.
23pub fn same_config_field(left: &Expr, right: &Expr) -> bool {
24    match (config_field_name(left), config_field_name(right)) {
25        (Some(left), Some(right)) => left == right,
26        _ => left == right,
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use sim_kernel::Symbol;
33
34    use super::*;
35
36    #[test]
37    fn config_field_name_is_key_identity_not_map_lookup() {
38        assert_eq!(
39            config_field_name(&Expr::Symbol(Symbol::new("mode"))),
40            Some("mode")
41        );
42        assert_eq!(
43            config_field_name(&Expr::String("mode".into())),
44            Some("mode")
45        );
46        assert_eq!(
47            config_field_name(&Expr::Symbol(Symbol::qualified("config", "mode"))),
48            None
49        );
50        assert_eq!(config_field_name(&Expr::Bool(true)), None);
51    }
52}