-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathdata.rs
More file actions
48 lines (45 loc) · 1.72 KB
/
Copy pathdata.rs
File metadata and controls
48 lines (45 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use stackable_operator::kube::{ResourceExt, api::DynamicObject};
pub fn containers(target: &mut DynamicObject) -> anyhow::Result<&mut Vec<serde_json::Value>> {
let tname = target.name_any();
let path = "template/spec/containers".split("/");
match get_or_create(target.data.pointer_mut("/spec").unwrap(), path)? {
serde_json::Value::Array(containers) => Ok(containers),
_ => anyhow::bail!("no containers found in object {tname}"),
}
}
/// Returns the object nested in `root` by traversing the `path` of nested keys.
/// Creates any missing objects in path.
/// In case of success, the returned value is either the existing object or
/// serde_json::Value::Null.
/// Returns an error if any of the nested objects has a type other than map.
pub fn get_or_create<'a, 'b, I>(
root: &'a mut serde_json::Value,
path: I,
) -> anyhow::Result<&'a mut serde_json::Value>
where
I: IntoIterator<Item = &'b str>,
{
let mut iter = path.into_iter();
match iter.next() {
None => Ok(root),
Some(first) => {
let new_root = get_or_insert_default_object(root, first)?;
get_or_create(new_root, iter)
}
}
}
/// Given a map object create or return the object corresponding to the given `key`.
fn get_or_insert_default_object<'a>(
value: &'a mut serde_json::Value,
key: &str,
) -> anyhow::Result<&'a mut serde_json::Value> {
let map = match value {
serde_json::Value::Object(map) => map,
x @ serde_json::Value::Null => {
*x = serde_json::json!({});
x.as_object_mut().unwrap()
}
x => anyhow::bail!("invalid type {x:?}, expected map"),
};
Ok(map.entry(key).or_insert_with(|| serde_json::Value::Null))
}