Skip to main content

rune/runtime/value/
serde.rs

1use core::fmt;
2
3use crate::alloc;
4use crate::alloc::prelude::*;
5use crate::runtime::{self, env, Bytes, Inline, Object, OwnedTuple, Repr, RttiKind, Vec};
6use crate::TypeHash;
7
8use serde::de::{self, Deserialize as _, Error as _};
9use serde::ser::{self, Error as _, SerializeMap as _, SerializeSeq as _};
10
11use super::Value;
12
13/// Deserialize implementation for value pointers.
14impl<'de> de::Deserialize<'de> for Value {
15    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
16    where
17        D: de::Deserializer<'de>,
18    {
19        // Building a value out of a document descends into it by recursing, and
20        // how deeply the document nests is decided by whoever wrote it, so the
21        // walk is bounded the same way every other walk over a value is.
22        let _guard = env::enter_value().map_err(D::Error::custom)?;
23        deserializer.deserialize_any(VmVisitor)
24    }
25}
26
27/// Serialize implementation for value pointers.
28impl ser::Serialize for Value {
29    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30    where
31        S: ser::Serializer,
32    {
33        // A value graph is built by the machine, so how deeply it nests has
34        // nothing to do with how deep the source was, and it can even be
35        // cyclic. Descending into it recurses, so the walk is bounded the same
36        // way comparing, ordering, hashing and formatting one is.
37        let _guard = env::enter_value().map_err(S::Error::custom)?;
38
39        match self.as_ref() {
40            Repr::Inline(value) => match *value {
41                Inline::Empty => Err(ser::Error::custom("cannot serialize empty values")),
42                Inline::Unit => serializer.serialize_unit(),
43                Inline::Bool(value) => serializer.serialize_bool(value),
44                Inline::Char(value) => serializer.serialize_char(value),
45                Inline::Unsigned(value) => serializer.serialize_u64(value),
46                Inline::Signed(value) => serializer.serialize_i64(value),
47                Inline::Float(value) => serializer.serialize_f64(value),
48                Inline::Type(..) => Err(ser::Error::custom("cannot serialize types")),
49                Inline::Ordering(..) => Err(ser::Error::custom("cannot serialize orderings")),
50                Inline::Hash(..) => Err(ser::Error::custom("cannot serialize type hashes")),
51            },
52            Repr::Dynamic(value) => match value.rtti().kind {
53                RttiKind::Empty => Err(ser::Error::custom(format!(
54                    "cannot serialize empty struct {}",
55                    value.rtti().item
56                ))),
57                RttiKind::Tuple => Err(ser::Error::custom(format!(
58                    "cannot serialize tuple struct {}",
59                    value.rtti().item
60                ))),
61                RttiKind::Struct => Err(ser::Error::custom(format!(
62                    "cannot serialize struct {}",
63                    value.rtti().item
64                ))),
65            },
66            Repr::Any(value) => match value.type_hash() {
67                Option::<Value>::HASH => {
68                    let option = value
69                        .borrow_ref::<Option<Value>>()
70                        .map_err(S::Error::custom)?;
71                    <Option<Value>>::serialize(&option, serializer)
72                }
73                String::HASH => {
74                    let string = value.borrow_ref::<String>().map_err(S::Error::custom)?;
75                    serializer.serialize_str(string.as_str())
76                }
77                Bytes::HASH => {
78                    let bytes = value.borrow_ref::<Bytes>().map_err(S::Error::custom)?;
79                    serializer.serialize_bytes(bytes.as_slice())
80                }
81                runtime::Vec::HASH => {
82                    let vec = value.borrow_ref::<Vec>().map_err(S::Error::custom)?;
83                    let mut serializer = serializer.serialize_seq(Some(vec.len()))?;
84
85                    for value in vec.iter() {
86                        serializer.serialize_element(value)?;
87                    }
88
89                    serializer.end()
90                }
91                OwnedTuple::HASH => {
92                    let tuple = value.borrow_ref::<OwnedTuple>().map_err(S::Error::custom)?;
93                    let mut serializer = serializer.serialize_seq(Some(tuple.len()))?;
94
95                    for value in tuple.iter() {
96                        serializer.serialize_element(value)?;
97                    }
98
99                    serializer.end()
100                }
101                Object::HASH => {
102                    let object = value.borrow_ref::<Object>().map_err(S::Error::custom)?;
103                    let mut serializer = serializer.serialize_map(Some(object.len()))?;
104
105                    for (key, value) in object.iter() {
106                        serializer.serialize_entry(key, value)?;
107                    }
108
109                    serializer.end()
110                }
111                _ => Err(ser::Error::custom("cannot serialize external references")),
112            },
113        }
114    }
115}
116
117struct VmVisitor;
118
119impl<'de> de::Visitor<'de> for VmVisitor {
120    type Value = Value;
121
122    #[inline]
123    fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
124        fmt.write_str("any valid value")
125    }
126
127    #[inline]
128    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
129    where
130        E: de::Error,
131    {
132        let v = v.try_to_owned().map_err(E::custom)?;
133        Value::try_from(v).map_err(E::custom)
134    }
135
136    #[inline]
137    fn visit_string<E>(self, v: rust_alloc::string::String) -> Result<Self::Value, E>
138    where
139        E: de::Error,
140    {
141        let v = alloc::String::try_from(v).map_err(E::custom)?;
142        Value::try_from(v).map_err(E::custom)
143    }
144
145    #[inline]
146    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
147    where
148        E: de::Error,
149    {
150        let v = alloc::Vec::try_from(v).map_err(E::custom)?;
151        let v = Bytes::from_vec(v);
152        Value::try_from(v).map_err(E::custom)
153    }
154
155    #[inline]
156    fn visit_byte_buf<E>(self, v: rust_alloc::vec::Vec<u8>) -> Result<Self::Value, E>
157    where
158        E: de::Error,
159    {
160        let v = alloc::Vec::try_from(v).map_err(E::custom)?;
161        let v = Bytes::from_vec(v);
162        Value::try_from(v).map_err(E::custom)
163    }
164
165    #[inline]
166    fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
167    where
168        E: de::Error,
169    {
170        Ok(Value::from(v as i64))
171    }
172
173    #[inline]
174    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
175    where
176        E: de::Error,
177    {
178        Ok(Value::from(v as i64))
179    }
180
181    #[inline]
182    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
183    where
184        E: de::Error,
185    {
186        Ok(Value::from(v as i64))
187    }
188
189    #[inline]
190    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
191    where
192        E: de::Error,
193    {
194        Ok(Value::from(v))
195    }
196
197    #[inline]
198    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
199    where
200        E: de::Error,
201    {
202        Ok(Value::from(v as i64))
203    }
204
205    #[inline]
206    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
207    where
208        E: de::Error,
209    {
210        Ok(Value::from(v as i64))
211    }
212
213    #[inline]
214    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
215    where
216        E: de::Error,
217    {
218        Ok(Value::from(v as i64))
219    }
220
221    #[inline]
222    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
223    where
224        E: de::Error,
225    {
226        Ok(Value::from(v as i64))
227    }
228
229    #[inline]
230    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
231    where
232        E: de::Error,
233    {
234        Ok(Value::from(v as i64))
235    }
236
237    #[inline]
238    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
239    where
240        E: de::Error,
241    {
242        Ok(Value::from(v as i64))
243    }
244
245    #[inline]
246    fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
247    where
248        E: de::Error,
249    {
250        Ok(Value::from(v as f64))
251    }
252
253    #[inline]
254    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
255    where
256        E: de::Error,
257    {
258        Ok(Value::from(v))
259    }
260
261    #[inline]
262    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
263    where
264        E: de::Error,
265    {
266        Ok(Value::from(v))
267    }
268
269    #[inline]
270    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
271    where
272        D: serde::Deserializer<'de>,
273    {
274        let some = Some(Value::deserialize(deserializer)?);
275        Value::try_from(some).map_err(D::Error::custom)
276    }
277
278    #[inline]
279    fn visit_none<E>(self) -> Result<Self::Value, E>
280    where
281        E: de::Error,
282    {
283        Value::try_from(None).map_err(E::custom)
284    }
285
286    #[inline]
287    fn visit_unit<E>(self) -> Result<Self::Value, E>
288    where
289        E: de::Error,
290    {
291        Ok(Value::unit())
292    }
293
294    #[inline]
295    fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
296    where
297        V: de::SeqAccess<'de>,
298    {
299        let mut vec = if let Some(hint) = visitor.size_hint() {
300            alloc::Vec::try_with_capacity(hint).map_err(V::Error::custom)?
301        } else {
302            alloc::Vec::new()
303        };
304
305        while let Some(elem) = visitor.next_element()? {
306            vec.try_push(elem).map_err(V::Error::custom)?;
307        }
308
309        let vec = Vec::from(vec);
310        Value::try_from(vec).map_err(V::Error::custom)
311    }
312
313    #[inline]
314    fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
315    where
316        V: de::MapAccess<'de>,
317    {
318        let mut object = Object::new();
319
320        while let Some((key, value)) = visitor.next_entry()? {
321            object.insert(key, value).map_err(V::Error::custom)?;
322        }
323
324        Value::try_from(object).map_err(V::Error::custom)
325    }
326}