conjure_cp_cli/utils/
json.rs1use serde_json::Value;
2
3fn json_value_cmp(a: &Value, b: &Value) -> std::cmp::Ordering {
8 match (a, b) {
9 (Value::Null, Value::Null) => std::cmp::Ordering::Equal,
10 (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
11 (Value::String(a), Value::String(b)) => a.cmp(b),
12 (Value::Number(a), Value::Number(b)) => {
13 let af = a.as_f64().unwrap_or_default();
14 let bf = b.as_f64().unwrap_or_default();
15 af.total_cmp(&bf)
16 }
17 (Value::Array(a), Value::Array(b)) => {
18 for (a, b) in a.iter().zip(b.iter()) {
19 let cmp = json_value_cmp(a, b);
20 if cmp != std::cmp::Ordering::Equal {
21 return cmp;
22 }
23 }
24 std::cmp::Ordering::Equal
25 }
26 _ => a.to_string().cmp(&b.to_string()),
27 }
28}
29
30pub fn sort_json_variables(value: &Value) -> Value {
33 match value {
34 Value::Array(vars) => {
35 let mut vars_sorted = vars.clone();
36 vars_sorted.sort_by(json_value_cmp);
37 Value::Array(vars_sorted)
38 }
39 _ => value.clone(),
40 }
41}
42
43pub fn sort_json_object(value: &Value, sort_arrays: bool) -> Value {
52 match value {
53 Value::Object(obj) => {
54 let mut ordered: Vec<(String, Value)> = obj
55 .iter()
56 .map(|(k, v)| {
57 if k == "variables" {
58 (k.clone(), sort_json_variables(v))
59 } else {
60 (k.clone(), sort_json_object(v, false))
61 }
62 })
63 .collect();
64
65 ordered.sort_by(|a, b| a.0.cmp(&b.0));
66 Value::Object(ordered.into_iter().collect())
67 }
68 Value::Array(arr) => {
69 let mut arr: Vec<Value> = arr.iter().map(|val| sort_json_object(val, false)).collect();
70
71 if sort_arrays {
72 arr.sort_by(json_value_cmp);
73 }
74
75 Value::Array(arr)
76 }
77 _ => value.clone(),
78 }
79}