use serde_json::Value;
pub fn step_key(step: &Value) -> String {
let mut stripped = step.clone();
strip_labels(&mut stripped);
crate::storage::content::canonical_json(&stripped)
}
pub fn step_key_keeping_names(step: &Value) -> String {
let mut stripped = step.clone();
strip_ids(&mut stripped);
crate::storage::content::canonical_json(&stripped)
}
fn strip_labels(step: &mut Value) {
if let Some(obj) = step.as_object_mut() {
obj.remove("id");
obj.remove("name");
if let Some(members) = obj.get_mut("tasks").and_then(Value::as_array_mut) {
members.iter_mut().for_each(strip_labels);
}
}
}
fn strip_ids(step: &mut Value) {
if let Some(obj) = step.as_object_mut() {
obj.remove("id");
if let Some(members) = obj.get_mut("tasks").and_then(Value::as_array_mut) {
members.iter_mut().for_each(strip_ids);
}
}
}
pub fn value_key(value: &Value) -> String {
crate::storage::content::canonical_json(value)
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn labels_do_not_change_a_step_key() {
let a =
json!({"id": "a", "name": "A", "function": {"name": "log", "input": {"message": "x"}}});
let b =
json!({"name": "B", "id": "b", "function": {"name": "log", "input": {"message": "x"}}});
assert_eq!(step_key(&a), step_key(&b));
let c =
json!({"id": "c", "name": "C", "function": {"name": "log", "input": {"message": "y"}}});
assert_ne!(step_key(&a), step_key(&c));
}
#[test]
fn group_members_are_stripped_too() {
let g1 = json!({"id": "g", "tasks": [{"id": "x", "name": "X", "function": {"name": "log", "input": {}}}]});
let g2 = json!({"id": "h", "tasks": [{"id": "y", "name": "Y", "function": {"name": "log", "input": {}}}]});
assert_eq!(step_key(&g1), step_key(&g2));
assert_ne!(step_key_keeping_names(&g1), step_key_keeping_names(&g2));
}
}