1use neo_types::*;
5use num_bigint::BigInt;
6use serde_json::{json, Value as JsonValue};
7use std::vec::Vec;
8
9pub struct NeoJSON;
11
12impl NeoJSON {
13 pub fn serialize(value: &NeoValue) -> NeoResult<NeoString> {
14 let json_value = Self::value_to_json(value)?;
15 let text = serde_json::to_string(&json_value)
16 .map_err(|err| NeoError::new(&format!("failed to serialize JSON: {err}")))?;
17 Ok(NeoString::from_str(&text))
18 }
19
20 pub fn deserialize(json: &NeoString) -> NeoResult<NeoValue> {
21 let parsed: JsonValue = serde_json::from_str(json.as_str())
22 .map_err(|err| NeoError::new(&format!("failed to parse JSON: {err}")))?;
23 Self::json_to_value(&parsed)
24 }
25
26 fn value_to_json(value: &NeoValue) -> NeoResult<JsonValue> {
27 match value {
28 NeoValue::Integer(i) => Ok(json!({
29 "type": "Integer",
30 "value": i.as_bigint().to_string()
31 })),
32 NeoValue::Boolean(b) => Ok(json!({
33 "type": "Boolean",
34 "value": b.as_bool()
35 })),
36 NeoValue::String(s) => Ok(json!({
37 "type": "String",
38 "value": s.as_str()
39 })),
40 NeoValue::ByteString(bs) => {
41 let bytes: Vec<JsonValue> =
42 bs.as_slice().iter().map(|b| JsonValue::from(*b)).collect();
43 Ok(json!({ "type": "ByteString", "value": bytes }))
44 }
45 NeoValue::Array(arr) => {
46 let mut values = Vec::new();
47 for item in arr.iter() {
48 values.push(Self::value_to_json(item)?);
49 }
50 Ok(json!({ "type": "Array", "value": values }))
51 }
52 NeoValue::Map(map) => {
53 let mut entries = Vec::new();
54 for (key, value) in map.iter() {
55 entries.push(json!({
56 "key": Self::value_to_json(key)?,
57 "value": Self::value_to_json(value)?,
58 }));
59 }
60 Ok(json!({ "type": "Map", "value": entries }))
61 }
62 NeoValue::Struct(st) => {
63 let mut fields_json = Vec::new();
64 for (name, value) in st.iter() {
65 fields_json.push(json!({
66 "name": name,
67 "value": Self::value_to_json(value)?,
68 }));
69 }
70 Ok(json!({ "type": "Struct", "value": fields_json }))
71 }
72 NeoValue::Null => Ok(json!({ "type": "Null" })),
73 }
74 }
75
76 fn json_to_value(json: &JsonValue) -> NeoResult<NeoValue> {
77 let obj = json.as_object().ok_or(NeoError::InvalidType)?;
78 let kind = obj
79 .get("type")
80 .and_then(JsonValue::as_str)
81 .ok_or(NeoError::InvalidType)?;
82
83 match kind {
84 "Integer" => {
85 let value_str = obj
86 .get("value")
87 .and_then(JsonValue::as_str)
88 .ok_or(NeoError::InvalidType)?;
89 let bigint =
90 BigInt::parse_bytes(value_str.as_bytes(), 10).ok_or(NeoError::InvalidType)?;
91 Ok(NeoValue::from(NeoInteger::new(bigint)))
92 }
93 "Boolean" => {
94 let value = obj
95 .get("value")
96 .and_then(JsonValue::as_bool)
97 .ok_or(NeoError::InvalidType)?;
98 Ok(NeoValue::from(NeoBoolean::new(value)))
99 }
100 "String" => {
101 let value = obj
102 .get("value")
103 .and_then(JsonValue::as_str)
104 .ok_or(NeoError::InvalidType)?;
105 Ok(NeoValue::from(NeoString::from_str(value)))
106 }
107 "ByteString" => {
108 let array = obj
109 .get("value")
110 .and_then(JsonValue::as_array)
111 .ok_or(NeoError::InvalidType)?;
112 let mut bytes = Vec::with_capacity(array.len());
113 for item in array {
114 let byte = item.as_u64().ok_or(NeoError::InvalidType)?;
115 let byte = u8::try_from(byte).map_err(|_| NeoError::InvalidType)?;
116 bytes.push(byte);
117 }
118 Ok(NeoValue::from(NeoByteString::new(bytes)))
119 }
120 "Array" => {
121 let array = obj
122 .get("value")
123 .and_then(JsonValue::as_array)
124 .ok_or(NeoError::InvalidType)?;
125 let mut values = NeoArray::new();
126 for item in array {
127 values.push(Self::json_to_value(item)?);
128 }
129 Ok(NeoValue::from(values))
130 }
131 "Map" => {
132 let entries = obj
133 .get("value")
134 .and_then(JsonValue::as_array)
135 .ok_or(NeoError::InvalidType)?;
136 let mut map = NeoMap::new();
137 for entry in entries {
138 let entry_obj = entry.as_object().ok_or(NeoError::InvalidType)?;
139 let key_json = entry_obj.get("key").ok_or(NeoError::InvalidType)?;
140 let value_json = entry_obj.get("value").ok_or(NeoError::InvalidType)?;
141 let key = Self::json_to_value(key_json)?;
142 let value = Self::json_to_value(value_json)?;
143 map.insert(key, value);
144 }
145 Ok(NeoValue::from(map))
146 }
147 "Struct" => {
148 let fields = obj
149 .get("value")
150 .and_then(JsonValue::as_array)
151 .ok_or(NeoError::InvalidType)?;
152 let mut result = NeoStruct::new();
153 for field in fields {
154 let field_obj = field.as_object().ok_or(NeoError::InvalidType)?;
155 let name = field_obj
156 .get("name")
157 .and_then(JsonValue::as_str)
158 .ok_or(NeoError::InvalidType)?;
159 let value_json = field_obj.get("value").ok_or(NeoError::InvalidType)?;
160 let value = Self::json_to_value(value_json)?;
161 result = result.with_field(name, value);
162 }
163 Ok(NeoValue::from(result))
164 }
165 "Null" => Ok(NeoValue::Null),
166 _ => Err(NeoError::InvalidType),
167 }
168 }
169}