alox_48/value/
ser.rs

1// Copyright (c) 2024 Lily Lyons
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6use super::{Object, RbFields, RbHash, RbString, Symbol, Userdata, Value};
7use crate::{
8    ser::{Error, Kind, Result, Serialize},
9    Instance, RbArray, RbStruct, SerializerTrait, Sym,
10};
11
12impl Serialize for Value {
13    fn serialize<S>(&self, serializer: S) -> Result<S::Ok>
14    where
15        S: SerializerTrait,
16    {
17        match self {
18            Value::Nil => serializer.serialize_nil(),
19            Value::Bool(v) => serializer.serialize_bool(*v),
20            Value::Float(f) => serializer.serialize_f64(*f),
21            Value::Integer(i) => serializer.serialize_i32(*i),
22            Value::String(s) => s.serialize(serializer),
23            Value::Symbol(s) => s.serialize(serializer),
24            Value::Array(a) => a.serialize(serializer),
25            Value::Hash(h) => h.serialize(serializer),
26            Value::Userdata(d) => d.serialize(serializer),
27            Value::Object(o) => o.serialize(serializer),
28            Value::Instance(i) => i.serialize(serializer),
29            Value::RbStruct(s) => s.serialize(serializer),
30            Value::Class(c) => serializer.serialize_class(c),
31            Value::Module(m) => serializer.serialize_module(m),
32            Value::Extended { module, value } => serializer.serialize_extended(module, value),
33            Value::UserClass { class, value } => serializer.serialize_user_class(class, value),
34            Value::UserMarshal { class, value } => serializer.serialize_user_marshal(class, value),
35            Value::Data { class, value } => serializer.serialize_data(class, value),
36            Value::Regex { data, flags } => {
37                serializer.serialize_regular_expression(data.as_slice(), *flags)
38            }
39        }
40    }
41}
42
43/// Serializer whose output is a `Value`.
44///
45/// This is the serializer that backs `to_value`.
46/// Unlike the main alox-48 serializer which goes from some value of `T` to binary data,
47/// this one goes from `T` to `Value`.
48#[derive(Clone, Copy, Debug)]
49pub struct Serializer;
50
51#[derive(Debug)]
52pub struct SerializeIvars {
53    fields: RbFields,
54    next_field: Option<Symbol>,
55    value: SerializeIvarsValue,
56}
57
58#[derive(Debug)]
59enum SerializeIvarsValue {
60    Instance(Value),
61    Object(Symbol),
62    Struct(Symbol),
63}
64
65#[derive(Debug)]
66pub struct SerializeHash {
67    hash: RbHash,
68    next_key: Option<Value>,
69}
70
71#[derive(Debug)]
72pub struct SerializeArray(RbArray);
73
74impl SerializerTrait for Serializer {
75    type Ok = Value;
76
77    type SerializeIvars = SerializeIvars;
78    type SerializeHash = SerializeHash;
79    type SerializeArray = SerializeArray;
80
81    fn serialize_nil(self) -> Result<Self::Ok> {
82        Ok(Value::Nil)
83    }
84
85    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
86        Ok(Value::Bool(v))
87    }
88
89    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
90        Ok(Value::Integer(v))
91    }
92
93    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
94        Ok(Value::Float(v))
95    }
96
97    fn serialize_hash(self, len: usize) -> Result<Self::SerializeHash> {
98        Ok(SerializeHash {
99            hash: RbHash::with_capacity(len),
100            next_key: None,
101        })
102    }
103
104    fn serialize_array(self, len: usize) -> Result<Self::SerializeArray> {
105        Ok(SerializeArray(Vec::with_capacity(len)))
106    }
107
108    fn serialize_string(self, data: &[u8]) -> Result<Self::Ok> {
109        Ok(Value::String(RbString {
110            data: data.to_vec(),
111        }))
112    }
113
114    fn serialize_symbol(self, sym: &Sym) -> Result<Self::Ok> {
115        Ok(Value::Symbol(sym.to_symbol()))
116    }
117
118    fn serialize_regular_expression(self, regex: &[u8], flags: u8) -> Result<Self::Ok> {
119        Ok(Value::Regex {
120            data: RbString::from(regex),
121            flags,
122        })
123    }
124
125    fn serialize_object(self, class: &Sym, len: usize) -> Result<Self::SerializeIvars> {
126        Ok(SerializeIvars {
127            fields: RbFields::with_capacity(len),
128            next_field: None,
129            value: SerializeIvarsValue::Object(class.to_symbol()),
130        })
131    }
132
133    fn serialize_struct(self, name: &Sym, len: usize) -> Result<Self::SerializeIvars> {
134        Ok(SerializeIvars {
135            fields: RbFields::with_capacity(len),
136            next_field: None,
137            value: SerializeIvarsValue::Struct(name.to_symbol()),
138        })
139    }
140
141    fn serialize_class(self, class: &Sym) -> Result<Self::Ok> {
142        Ok(Value::Class(class.to_symbol()))
143    }
144
145    fn serialize_module(self, module: &Sym) -> Result<Self::Ok> {
146        Ok(Value::Module(module.to_symbol()))
147    }
148
149    fn serialize_instance<V>(self, value: &V, len: usize) -> Result<Self::SerializeIvars>
150    where
151        V: Serialize + ?Sized,
152    {
153        let value = value.serialize(Serializer)?;
154        Ok(SerializeIvars {
155            fields: RbFields::with_capacity(len),
156            next_field: None,
157            value: SerializeIvarsValue::Instance(value),
158        })
159    }
160
161    fn serialize_extended<V>(self, module: &Sym, value: &V) -> Result<Self::Ok>
162    where
163        V: Serialize + ?Sized,
164    {
165        let value = value.serialize(Serializer)?;
166        Ok(Value::Extended {
167            module: module.to_symbol(),
168            value: Box::new(value),
169        })
170    }
171
172    fn serialize_user_class<V>(self, class: &Sym, value: &V) -> Result<Self::Ok>
173    where
174        V: Serialize + ?Sized,
175    {
176        let value = value.serialize(Serializer)?;
177        Ok(Value::UserClass {
178            class: class.to_symbol(),
179            value: Box::new(value),
180        })
181    }
182
183    fn serialize_user_data(self, class: &Sym, data: &[u8]) -> Result<Self::Ok> {
184        Ok(Value::Userdata(Userdata {
185            class: class.to_symbol(),
186            data: data.to_vec(),
187        }))
188    }
189
190    fn serialize_user_marshal<V>(self, class: &Sym, value: &V) -> Result<Self::Ok>
191    where
192        V: Serialize + ?Sized,
193    {
194        let value = value.serialize(Serializer)?;
195        Ok(Value::UserMarshal {
196            class: class.to_symbol(),
197            value: Box::new(value),
198        })
199    }
200
201    fn serialize_data<V>(self, class: &Sym, value: &V) -> Result<Self::Ok>
202    where
203        V: Serialize + ?Sized,
204    {
205        let value = value.serialize(Serializer)?;
206        Ok(Value::Data {
207            class: class.to_symbol(),
208            value: Box::new(value),
209        })
210    }
211}
212
213impl crate::SerializeIvars for SerializeIvars {
214    type Ok = Value;
215
216    fn serialize_field(&mut self, k: &Sym) -> Result<()> {
217        if self.next_field.is_some() {
218            return Err(Error {
219                kind: Kind::KeyAfterKey,
220            });
221        }
222        self.next_field = Some(k.to_symbol());
223        Ok(())
224    }
225
226    fn serialize_value<V>(&mut self, v: &V) -> Result<()>
227    where
228        V: Serialize + ?Sized,
229    {
230        let field = self.next_field.take().ok_or(Error {
231            kind: Kind::ValueAfterValue,
232        })?;
233
234        let value = v.serialize(Serializer)?;
235        self.fields.insert(field, value);
236
237        Ok(())
238    }
239
240    fn end(self) -> Result<Self::Ok> {
241        match self.value {
242            SerializeIvarsValue::Object(class) => Ok(Value::Object(Object {
243                class,
244                fields: self.fields,
245            })),
246            SerializeIvarsValue::Instance(value) => Ok(Value::Instance(Instance {
247                value: Box::new(value),
248                fields: self.fields,
249            })),
250            SerializeIvarsValue::Struct(class) => Ok(Value::RbStruct(RbStruct {
251                class,
252                fields: self.fields,
253            })),
254        }
255    }
256}
257
258impl crate::SerializeHash for SerializeHash {
259    type Ok = Value;
260
261    fn serialize_key<K>(&mut self, k: &K) -> Result<()>
262    where
263        K: Serialize + ?Sized,
264    {
265        if self.next_key.is_some() {
266            return Err(Error {
267                kind: Kind::KeyAfterKey,
268            });
269        }
270        let value = k.serialize(Serializer)?;
271        self.next_key = Some(value);
272        Ok(())
273    }
274
275    fn serialize_value<V>(&mut self, v: &V) -> Result<()>
276    where
277        V: Serialize + ?Sized,
278    {
279        let key = self.next_key.take().ok_or(Error {
280            kind: Kind::ValueAfterValue,
281        })?;
282
283        let value = v.serialize(Serializer)?;
284        self.hash.insert(key, value);
285
286        Ok(())
287    }
288
289    fn end(self) -> Result<Self::Ok> {
290        Ok(Value::Hash(self.hash))
291    }
292}
293
294impl crate::SerializeArray for SerializeArray {
295    type Ok = Value;
296
297    fn serialize_element<T>(&mut self, v: &T) -> Result<()>
298    where
299        T: Serialize + ?Sized,
300    {
301        let value = v.serialize(Serializer)?;
302        self.0.push(value);
303        Ok(())
304    }
305
306    fn end(self) -> Result<Self::Ok> {
307        Ok(Value::Array(self.0))
308    }
309}