code_ranker_graph/
serialize.rs1use serde::Serialize;
8
9pub fn to_canonical_string_pretty<T: Serialize>(value: &T) -> serde_json::Result<String> {
13 let mut v = serde_json::to_value(value)?;
14 canonicalize_value(&mut v);
15 serde_json::to_string_pretty(&v)
16}
17
18pub fn to_canonical_string<T: Serialize>(value: &T) -> serde_json::Result<String> {
20 let mut v = serde_json::to_value(value)?;
21 canonicalize_value(&mut v);
22 serde_json::to_string(&v)
23}
24
25fn canonicalize_value(v: &mut serde_json::Value) {
26 match v {
27 serde_json::Value::Array(arr) => {
28 for item in arr.iter_mut() {
29 canonicalize_value(item);
30 }
31 }
32 serde_json::Value::Object(map) => {
33 for val in map.values_mut() {
34 canonicalize_value(val);
35 }
36 if let Some(serde_json::Value::Array(nodes)) = map.get_mut("nodes") {
37 nodes.sort_by_key(|a| json_str(a, "id"));
38 }
39 if let Some(serde_json::Value::Array(edges)) = map.get_mut("edges") {
40 edges.sort_by(|a, b| {
41 json_str(a, "source")
42 .cmp(&json_str(b, "source"))
43 .then_with(|| json_str(a, "target").cmp(&json_str(b, "target")))
44 .then_with(|| json_str(a, "kind").cmp(&json_str(b, "kind")))
45 });
46 }
47 }
48 _ => {}
49 }
50}
51
52fn json_str(v: &serde_json::Value, key: &str) -> String {
53 v.get(key)
54 .and_then(|x| x.as_str())
55 .unwrap_or_default()
56 .to_string()
57}