acp_runtime/
json_support.rs1use serde::Serialize;
6use serde::de::DeserializeOwned;
7use serde_json::{Map, Value};
8
9use crate::errors::{AcpError, AcpResult};
10
11pub type JsonMap = Map<String, Value>;
12
13pub fn to_json<T: Serialize>(value: &T) -> AcpResult<String> {
14 serde_json::to_string(value).map_err(AcpError::from)
15}
16
17pub fn from_json<T: DeserializeOwned>(value: &str) -> AcpResult<T> {
18 serde_json::from_str(value).map_err(AcpError::from)
19}
20
21pub fn to_value<T: Serialize>(value: &T) -> AcpResult<Value> {
22 serde_json::to_value(value).map_err(AcpError::from)
23}
24
25pub fn to_map<T: Serialize>(value: &T) -> AcpResult<JsonMap> {
26 match to_value(value)? {
27 Value::Object(map) => Ok(map),
28 _ => Err(AcpError::Validation("expected JSON object".to_string())),
29 }
30}
31
32pub fn value_to_map(value: Value) -> AcpResult<JsonMap> {
33 match value {
34 Value::Object(map) => Ok(map),
35 _ => Err(AcpError::Validation("expected JSON object".to_string())),
36 }
37}
38
39pub fn map_from_json(value: &str) -> AcpResult<JsonMap> {
40 match serde_json::from_str::<Value>(value)? {
41 Value::Object(map) => Ok(map),
42 _ => Err(AcpError::Validation(
43 "unable to parse JSON object".to_string(),
44 )),
45 }
46}
47
48pub fn convert<T: DeserializeOwned>(value: &Value) -> AcpResult<T> {
49 serde_json::from_value(value.clone()).map_err(AcpError::from)
50}
51
52pub fn canonical_json_string(value: &Value) -> AcpResult<String> {
53 let normalized = normalize_json(value);
54 serde_json::to_string(&normalized).map_err(AcpError::from)
55}
56
57pub fn canonical_json_bytes(value: &Value) -> AcpResult<Vec<u8>> {
58 Ok(canonical_json_string(value)?.into_bytes())
59}
60
61fn normalize_json(value: &Value) -> Value {
62 match value {
63 Value::Object(map) => {
64 let mut keys = map.keys().cloned().collect::<Vec<_>>();
65 keys.sort();
66 let mut out = JsonMap::new();
67 for key in keys {
68 if let Some(item) = map.get(&key) {
69 out.insert(key, normalize_json(item));
70 }
71 }
72 Value::Object(out)
73 }
74 Value::Array(items) => Value::Array(items.iter().map(normalize_json).collect()),
75 _ => value.clone(),
76 }
77}