1mod r#impl;
16
17use crate::analysis::AnalysedType;
18use crate::ValueAndType;
19use serde::ser::Error;
20use serde::{Deserialize, Serialize, Serializer};
21use serde_json::Value as JsonValue;
22
23pub trait ValueAndTypeJsonExtensions: Sized {
24 fn parse_with_type(json_val: &JsonValue, typ: &AnalysedType) -> Result<Self, Vec<String>>;
27
28 fn to_json_value(&self) -> Result<JsonValue, String>;
33}
34
35#[derive(Serialize, Deserialize)]
37struct ValueAndTypeJson {
38 typ: AnalysedType,
39 value: serde_json::Value,
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49pub struct OptionallyValueAndTypeJson {
50 pub typ: Option<AnalysedType>,
51 pub value: serde_json::Value,
52}
53
54impl OptionallyValueAndTypeJson {
55 pub fn has_type(&self) -> bool {
56 self.typ.is_some()
57 }
58
59 pub fn into_json_value(self) -> serde_json::Value {
60 self.value
61 }
62
63 pub fn into_value_and_type(self, typ: AnalysedType) -> Result<ValueAndType, Vec<String>> {
64 ValueAndType::parse_with_type(&self.value, &typ)
65 }
66
67 pub fn try_into_value_and_type(self) -> Result<Option<ValueAndType>, Vec<String>> {
68 match self.typ {
69 Some(typ) => ValueAndType::parse_with_type(&self.value, &typ).map(Some),
70 None => Ok(None),
71 }
72 }
73}
74
75impl TryFrom<ValueAndType> for OptionallyValueAndTypeJson {
76 type Error = String;
77
78 fn try_from(vnt: ValueAndType) -> Result<Self, Self::Error> {
79 let value = vnt.to_json_value()?;
80 Ok(OptionallyValueAndTypeJson {
81 typ: Some(vnt.typ),
82 value,
83 })
84 }
85}
86
87impl Serialize for ValueAndType {
88 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89 where
90 S: Serializer,
91 {
92 let typ = self.typ.clone();
93 let value = self.to_json_value().map_err(Error::custom)?;
94 let json = ValueAndTypeJson { typ, value };
95 json.serialize(serializer)
96 }
97}
98
99impl<'de> Deserialize<'de> for ValueAndType {
100 fn deserialize<D>(deserializer: D) -> Result<ValueAndType, D::Error>
101 where
102 D: serde::Deserializer<'de>,
103 {
104 let json = ValueAndTypeJson::deserialize(deserializer)?;
105 let value = ValueAndType::parse_with_type(&json.value, &json.typ).map_err(|err| {
106 serde::de::Error::custom(format!(
107 "Invalid type-annotated JSON value: {}",
108 err.join(", ")
109 ))
110 })?;
111 Ok(value)
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use test_r::test;
118
119 use crate::analysis::analysed_type::{result_err, result_ok, str, tuple};
120 use crate::{IntoValueAndType, Value, ValueAndType};
121
122 use serde_json::json;
123
124 #[test]
125 fn example1() {
126 let vnt = (10u32, "hello".to_string()).into_value_and_type();
127 let json = serde_json::to_value(&vnt).unwrap();
128 assert_eq!(
129 json,
130 json!({
131 "typ": {
132 "type": "Tuple",
133 "items": [
134 { "type": "U32" },
135 { "type": "Str" }
136 ]
137 },
138 "value": [10, "hello"]
139 })
140 );
141
142 let tav2: ValueAndType = serde_json::from_value(json).unwrap();
143 assert_eq!(vnt, tav2);
144 }
145
146 #[test]
147 fn example2() {
148 let vnt = ValueAndType {
149 typ: tuple(vec![result_err(str())]),
150 value: Value::Tuple(vec![Value::Result(Ok(None))]),
151 };
152 let json = serde_json::to_value(&vnt).unwrap();
153 assert_eq!(
154 json,
155 json!({
156 "typ": {
157 "type": "Tuple",
158 "items": [
159 {
160 "type": "Result",
161 "err": {
162 "type": "Str"
163 },
164 "ok": null
165 },
166 ]
167 },
168 "value": [{ "ok": null }]
169 })
170 );
171
172 let tav2: ValueAndType = serde_json::from_value(json).unwrap();
173 assert_eq!(vnt, tav2);
174 }
175
176 #[test]
177 fn example3() {
178 let vnt = ValueAndType {
179 typ: tuple(vec![result_ok(str())]),
180 value: Value::Tuple(vec![Value::Result(Err(None))]),
181 };
182 let json = serde_json::to_value(&vnt).unwrap();
183 assert_eq!(
184 json,
185 json!({
186 "typ": {
187 "type": "Tuple",
188 "items": [
189 {
190 "type": "Result",
191 "ok": {
192 "type": "Str"
193 },
194 "err": null
195 },
196 ]
197 },
198 "value": [{ "err": null }]
199 })
200 );
201
202 let tav2: ValueAndType = serde_json::from_value(json).unwrap();
203 assert_eq!(vnt, tav2);
204 }
205}