Skip to content

Commit

Permalink
Implement support for constant keys in our Mapping type
Browse files Browse the repository at this point in the history
We implement handling of constant keys (keys prefixed with
`KeyPrefix::Constant`) directly in the Mapping implementation. Keys with
other prefixes are inserted into the map unchanged.

To make the implementation more streamlined (and potentially faster), we
switch the type of `const_keys` to be a `HashSet` instead of a `Vec`,
which gives us `O(1)` removal of elements (for `Mapping::remove()`).

To insure integrity of the constant key tracking, We remove the
`map_as_mut()` method on the Mapping implementation which would allow
callers to break the constant key invariants that the other functions
provide.

Some functions (`insert`, `get_mut`, and `entry`) will return an Error
value when called for a key that's marked constant.
  • Loading branch information
simu committed Sep 1, 2023
1 parent 0870274 commit e4c3432
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 65 deletions.
5 changes: 3 additions & 2 deletions src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ impl Node {

// Convert serde_yaml::Mapping into our own Mapping type
let mut params: Mapping = n._params.clone().into();
// Inject `_reclass_` meta parameter into parameters
params.insert("_reclass_".into(), n.meta.as_reclass().into());
// Inject `_reclass_` meta parameter into parameters, return an error if someone has marked
// `_reclass_` or a subkey of it as constant.
params.insert("_reclass_".into(), n.meta.as_reclass().into())?;
n.parameters = params;

Ok(n)
Expand Down
26 changes: 16 additions & 10 deletions src/node/nodeinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,24 @@ impl NodeInfoMeta {

/// Generates a Mapping suitable to use as meta parameter `_reclass_`
pub(crate) fn as_reclass(&self) -> Mapping {
let mut namedata = Mapping::new();
namedata.insert("full".into(), self.name.clone().into());
namedata.insert(
"parts".into(),
Value::Sequence(vec![self.name.clone().into()]),
);
namedata.insert("path".into(), self.name.clone().into());
namedata.insert("short".into(), self.name.clone().into());
let namedata: Vec<(Value, Value)> = vec![
("full".into(), self.name.clone().into()),
(
"parts".into(),
Value::Sequence(vec![self.name.clone().into()]),
),
("path".into(), self.name.clone().into()),
("short".into(), self.name.clone().into()),
];
let namedata = Mapping::from_iter(namedata);

let mut pmeta = Mapping::new();
pmeta.insert("environment".into(), self.environment.clone().into());
pmeta.insert("name".into(), Value::Mapping(namedata));
pmeta
.insert("environment".into(), self.environment.clone().into())
.unwrap();
pmeta
.insert("name".into(), Value::Mapping(namedata))
.unwrap();

pmeta
}
Expand Down
Loading

0 comments on commit e4c3432

Please sign in to comment.