gluon_vm/api/
json.rs

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        // serde_json outputs valid UTF-8
38        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}