1extern crate serde_json;
2
3use std::{borrow::Borrow, fmt, result::Result as StdResult};
4
5use crate::base::types::ArcType;
6
7use crate::{
8 api::{Getable, OpaqueValue, ValueRef, VmInt, VmType},
9 thread::{ActiveThread, RootedThread, Thread, ThreadInternal},
10 ExternModule, Result, Variants,
11};
12
13use crate::serde::de::{self, DeserializeState, MapAccess, SeqAccess, Visitor};
14
15pub fn load(vm: &Thread) -> Result<ExternModule> {
16 fn deserialize(value: crate::api::WithVM<&str>) -> StdResult<JsonValue, String> {
17 let crate::api::WithVM { vm, value: input } = value;
18 let mut context = vm.current_context();
19 JsonValue::deserialize_state(&mut context, &mut serde_json::Deserializer::from_str(input))
20 .map_err(|err| err.to_string())
21 }
22
23 fn serialize<F>(value: crate::api::WithVM<Value>, formatter: F) -> StdResult<String, String>
24 where
25 F: serde_json::ser::Formatter,
26 {
27 let crate::api::WithVM { vm, value: input } = value;
28
29 let mut output = Vec::new();
30 SerializeState::serialize_state(
31 &input,
32 &mut serde_json::Serializer::with_formatter(&mut output, formatter),
33 vm,
34 )
35 .map_err(|err| err.to_string())?;
36
37 unsafe { Ok(String::from_utf8_unchecked(output)) }
39 }
40
41 ExternModule::new(
42 vm,
43 record! {
44 deserialize => primitive!(
45 1,
46 "std.json.prim.deserialize",
47 deserialize
48 ),
49 serialize => primitive!(
50 1,
51 "std.json.prim.serialize",
52 |v| serialize(v, serde_json::ser::CompactFormatter)
53 ),
54 serialize_pretty => primitive!(
55 1,
56 "std.json.prim.serialize_pretty",
57 |v| serialize(v, serde_json::ser::PrettyFormatter::new())
58 ),
59 },
60 )
61}
62
63impl VmType for serde_json::Value {
64 type Type = Self;
65 fn make_type(vm: &Thread) -> ArcType {
66 JsonValue::make_type(vm)
67 }
68}
69
70impl<'vm> crate::api::Pushable<'vm> for serde_json::Value {
71 fn vm_push(self, context: &mut ActiveThread<'vm>) -> Result<()> {
72 use serde_json::Value::*;
73 let tag = match self {
74 Null => {
75 context.context().push_new_data(0, 0)?;
76 return Ok(());
77 }
78 Bool(b) => {
79 b.vm_push(context)?;
80 1
81 }
82 Number(n) => {
83 if let Some(i) = n.as_i64() {
84 i.vm_push(context)?;
85 2
86 } else if let Some(i) = n.as_u64() {
87 i.vm_push(context)?;
88 2
89 } else if let Some(i) = n.as_f64() {
90 i.vm_push(context)?;
91 3
92 } else {
93 return Err(format!("Unable to marshal serde_json::Number({})", n).into());
94 }
95 }
96 String(s) => {
97 s.vm_push(context)?;
98 4
99 }
100 Array(a) => {
101 a.vm_push(context)?;
102 5
103 }
104 Object(o) => {
105 crate::api::to_gluon_map(o, context)?;
106 6
107 }
108 };
109 context.context().push_new_data(tag, 1)?;
110 Ok(())
111 }
112}
113
114impl<'vm, 'value> crate::api::Getable<'vm, 'value> for serde_json::Value {
115 impl_getable_simple!();
116
117 fn from_value(vm: &'vm Thread, value: Variants<'value>) -> Self {
118 match value.as_ref() {
119 ValueRef::Data(data) => match data.tag() {
120 0 => serde_json::Value::Null,
121 1 => serde_json::Value::Bool(bool::from_value(vm, data.get_variant(0).unwrap())),
122 2 => serde_json::Value::Number(
123 VmInt::from_value(vm, data.get_variant(0).unwrap()).into(),
124 ),
125 3 => serde_json::Value::Number(
126 serde_json::Number::from_f64(f64::from_value(vm, data.get_variant(0).unwrap()))
127 .unwrap(),
128 ),
129 4 => {
130 serde_json::Value::String(String::from_value(vm, data.get_variant(0).unwrap()))
131 }
132 5 => serde_json::Value::Array(Vec::from_value(vm, data.get_variant(0).unwrap())),
133 6 => {
134 let mut map = Default::default();
135 let inner = data.get_variant(0).unwrap();
136 crate::api::from_gluon_map(&mut map, vm, inner);
137 serde_json::Value::Object(map)
138 }
139 _ => ice!("ValueRef has a wrong tag: {}", data.tag()),
140 },
141 _ => ice!("ValueRef is not a std.json.Value"),
142 }
143 }
144}
145
146#[derive(Pushable, Getable, SerializeState)]
147#[serde(serialize_state = "Thread")]
148#[gluon(gluon_vm)]
149#[serde(untagged)]
150pub enum Value {
151 Null,
152 Bool(bool),
153 Int(i64),
154 Float(f64),
155 String(#[serde(state)] JsonString),
156 Array(#[serde(state)] Vec<JsonValue>),
157 Object(#[serde(state)] ::std::collections::BTreeMap<JsonString, JsonValue>),
158}
159
160#[derive(SerializeState, Ord, Eq, PartialEq, PartialOrd, Getable, Pushable)]
161#[serde(serialize_state = "Thread")]
162#[gluon(gluon_vm)]
163pub struct JsonString(OpaqueValue<RootedThread, str>);
164
165impl VmType for JsonString {
166 type Type = String;
167}
168
169impl ::std::ops::Deref for JsonString {
170 type Target = str;
171
172 fn deref(&self) -> &str {
173 &self.0
174 }
175}
176
177impl Borrow<str> for JsonString {
178 fn borrow(&self) -> &str {
179 self
180 }
181}
182
183impl<'de> de::DeserializeState<'de, ActiveThread<'de>> for JsonString {
184 fn deserialize_state<D>(
185 thread: &mut ActiveThread<'de>,
186 deserializer: D,
187 ) -> StdResult<Self, D::Error>
188 where
189 D: de::Deserializer<'de>,
190 {
191 struct StringVisitor<'a, 'vm: 'a>(&'a mut ActiveThread<'vm>);
192
193 impl<'a, 'de> Visitor<'de> for StringVisitor<'a, 'de> {
194 type Value = JsonString;
195
196 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
197 formatter.write_str("a string")
198 }
199
200 #[inline]
201 fn visit_str<E>(self, value: &str) -> StdResult<Self::Value, E>
202 where
203 E: de::Error,
204 {
205 crate::api::convert_with_active_thread(self.0, value).map_err(E::custom)
206 }
207 }
208
209 deserializer.deserialize_string(StringVisitor(thread))
210 }
211}
212
213impl VmType for Value {
214 type Type = Self;
215 fn make_type(vm: &Thread) -> ArcType {
216 JsonValue::make_type(vm)
217 }
218}
219
220#[derive(VmType)]
221#[gluon(vm_type = "std.json.Value")]
222#[gluon(gluon_vm)]
223pub struct JsonValue(crate::vm::RootedValue<RootedThread>);
224
225impl<'vm> crate::api::Pushable<'vm> for JsonValue {
226 fn vm_push(self, context: &mut ActiveThread<'vm>) -> Result<()> {
227 crate::api::Pushable::vm_push(self.0, context)
228 }
229}
230
231impl<'vm, 'value> crate::api::Getable<'vm, 'value> for JsonValue {
232 impl_getable_simple!();
233
234 fn from_value(vm: &'vm Thread, value: Variants<'value>) -> Self {
235 JsonValue(crate::api::Getable::from_value(vm, value))
236 }
237}
238
239use crate::serde::ser::{SerializeState, Serializer};
240impl SerializeState<Thread> for JsonValue {
241 fn serialize_state<S>(&self, serializer: S, vm: &Thread) -> StdResult<S::Ok, S::Error>
242 where
243 S: Serializer,
244 {
245 Value::from_value(vm, self.0.get_variant()).serialize_state(serializer, vm)
246 }
247}
248
249impl<'de> de::DeserializeState<'de, ActiveThread<'de>> for JsonValue {
250 fn deserialize_state<D>(
251 thread: &mut ActiveThread<'de>,
252 deserializer: D,
253 ) -> StdResult<Self, D::Error>
254 where
255 D: de::Deserializer<'de>,
256 {
257 struct ValueVisitor<'a, 'vm: 'a>(&'a mut ActiveThread<'vm>);
258
259 impl<'a, 'vm> ValueVisitor<'a, 'vm> {
260 fn marshal<T>(&mut self, value: T) -> JsonValue
261 where
262 T: crate::api::Pushable<'vm>,
263 {
264 let context = &mut *self.0;
265 value
266 .vm_push(context)
267 .unwrap_or_else(|err| panic!("{}", err));
268 let thread = context.thread();
269 let value = context.pop();
270 JsonValue(thread.root_value((*value).clone()))
271 }
272 }
273
274 impl<'a, 'de> Visitor<'de> for ValueVisitor<'a, 'de> {
275 type Value = JsonValue;
276
277 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
278 formatter.write_str("any valid JSON value")
279 }
280
281 #[inline]
282 fn visit_bool<E>(mut self, value: bool) -> StdResult<Self::Value, E> {
283 Ok(self.marshal(Value::Bool(value)))
284 }
285
286 #[inline]
287 fn visit_i64<E>(mut self, value: i64) -> StdResult<Self::Value, E> {
288 Ok(self.marshal(Value::Int(value.into())))
289 }
290
291 #[inline]
292 fn visit_u64<E>(mut self, value: u64) -> StdResult<Self::Value, E> {
293 Ok(self.marshal(Value::Int(value as i64)))
294 }
295
296 #[inline]
297 fn visit_f64<E>(mut self, value: f64) -> StdResult<Self::Value, E> {
298 Ok(self.marshal(Value::Float(value)))
299 }
300
301 #[inline]
302 fn visit_str<E>(mut self, value: &str) -> StdResult<Self::Value, E>
303 where
304 E: de::Error,
305 {
306 let value =
307 crate::api::convert_with_active_thread(self.0, value).map_err(E::custom)?;
308 Ok(self.marshal(Value::String(value)))
309 }
310
311 #[inline]
312 fn visit_string<E>(mut self, value: String) -> StdResult<Self::Value, E>
313 where
314 E: de::Error,
315 {
316 let value =
317 crate::api::convert_with_active_thread(self.0, value).map_err(E::custom)?;
318 Ok(self.marshal(Value::String(value)))
319 }
320
321 #[inline]
322 fn visit_none<E>(mut self) -> StdResult<Self::Value, E> {
323 Ok(self.marshal(Value::Null))
324 }
325
326 #[inline]
327 fn visit_some<D>(self, deserializer: D) -> StdResult<Self::Value, D::Error>
328 where
329 D: de::Deserializer<'de>,
330 {
331 de::DeserializeState::deserialize_state(&mut *self.0, deserializer)
332 }
333
334 #[inline]
335 fn visit_unit<E>(mut self) -> StdResult<Self::Value, E> {
336 Ok(self.marshal(Value::Null))
337 }
338
339 #[inline]
340 fn visit_seq<V>(mut self, mut visitor: V) -> StdResult<Self::Value, V::Error>
341 where
342 V: SeqAccess<'de>,
343 {
344 let mut vec = Vec::new();
345
346 while let Some(elem) = visitor.next_element_seed(de::Seed::new(&mut *self.0))? {
347 vec.push(elem);
348 }
349
350 Ok(self.marshal(Value::Array(vec)))
351 }
352
353 fn visit_map<V>(mut self, mut visitor: V) -> StdResult<Self::Value, V::Error>
354 where
355 V: MapAccess<'de>,
356 {
357 let mut values = ::std::collections::BTreeMap::new();
358
359 while let Some(key) = visitor.next_key_seed(de::Seed::new(&mut *self.0))? {
360 let value = visitor.next_value_seed(de::Seed::new(&mut *self.0))?;
361 values.insert(key, value);
362 }
363
364 Ok(self.marshal(Value::Object(values)))
365 }
366 }
367
368 deserializer.deserialize_any(ValueVisitor(thread))
369 }
370}