alox_48/value/
de.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 crate::{
7    de::{DeserializeSeed, Error, Kind, Result},
8    ArrayAccess, Deserialize, DeserializerTrait, HashAccess, Instance, InstanceAccess, IvarAccess,
9    Object, RbFields, RbHash, RbString, Sym, Userdata, Value, Visitor, VisitorInstance,
10    VisitorOption,
11};
12
13struct ValueVisitor;
14
15impl<'de> Visitor<'de> for ValueVisitor {
16    type Value = Value;
17
18    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        formatter.write_str("any ruby value")
20    }
21
22    fn visit_nil(self) -> Result<Self::Value> {
23        Ok(Value::Nil)
24    }
25
26    fn visit_bool(self, v: bool) -> Result<Self::Value> {
27        Ok(Value::Bool(v))
28    }
29
30    fn visit_i32(self, v: i32) -> Result<Self::Value> {
31        Ok(Value::Integer(v))
32    }
33
34    fn visit_f64(self, v: f64) -> Result<Self::Value> {
35        Ok(Value::Float(v))
36    }
37
38    fn visit_hash<A>(self, mut map: A) -> Result<Self::Value>
39    where
40        A: HashAccess<'de>,
41    {
42        let mut hash = RbHash::with_capacity(map.len());
43        while let Some((k, v)) = map.next_entry()? {
44            hash.insert(k, v);
45        }
46        Ok(Value::Hash(hash))
47    }
48
49    fn visit_array<A>(self, mut access: A) -> Result<Self::Value>
50    where
51        A: ArrayAccess<'de>,
52    {
53        let mut array = Vec::with_capacity(access.len());
54        while let Some(v) = access.next_element()? {
55            array.push(v);
56        }
57        Ok(Value::Array(array))
58    }
59
60    fn visit_string(self, string: &'de [u8]) -> Result<Self::Value> {
61        Ok(Value::String(RbString {
62            data: string.to_vec(),
63        }))
64    }
65
66    fn visit_symbol(self, symbol: &'de Sym) -> Result<Self::Value> {
67        Ok(Value::Symbol(symbol.to_symbol()))
68    }
69
70    fn visit_regular_expression(self, data: &'de [u8], flags: u8) -> Result<Self::Value> {
71        Ok(Value::Regex {
72            data: RbString::from(data),
73            flags,
74        })
75    }
76
77    fn visit_object<A>(self, class: &'de Sym, mut instance_variables: A) -> Result<Self::Value>
78    where
79        A: IvarAccess<'de>,
80    {
81        let mut fields = RbFields::with_capacity(instance_variables.len());
82        while let Some((k, v)) = instance_variables.next_entry()? {
83            fields.insert(k.to_symbol(), v);
84        }
85        Ok(Value::Object(Object {
86            class: class.to_symbol(),
87            fields,
88        }))
89    }
90
91    fn visit_struct<A>(self, name: &'de Sym, mut members: A) -> Result<Self::Value>
92    where
93        A: IvarAccess<'de>,
94    {
95        let mut fields = RbFields::with_capacity(members.len());
96        while let Some((k, v)) = members.next_entry()? {
97            fields.insert(k.to_symbol(), v);
98        }
99        Ok(Value::RbStruct(crate::RbStruct {
100            class: name.to_symbol(),
101            fields,
102        }))
103    }
104
105    fn visit_class(self, class: &'de Sym) -> Result<Self::Value> {
106        Ok(Value::Class(class.to_symbol()))
107    }
108
109    fn visit_module(self, module: &'de Sym) -> Result<Self::Value> {
110        Ok(Value::Module(module.to_symbol()))
111    }
112
113    fn visit_instance<A>(self, instance: A) -> Result<Self::Value>
114    where
115        A: InstanceAccess<'de>,
116    {
117        let (value, mut instance_fields) = instance.value()?;
118        let mut fields = RbFields::with_capacity(instance_fields.len());
119        while let Some((field, value)) = instance_fields.next_entry()? {
120            fields.insert(field.to_symbol(), value);
121        }
122        let instance = Instance {
123            value: Box::new(value),
124            fields,
125        };
126
127        Ok(Value::Instance(instance))
128    }
129
130    fn visit_extended<D>(self, module: &'de Sym, deserializer: D) -> Result<Self::Value>
131    where
132        D: DeserializerTrait<'de>,
133    {
134        let value = deserializer.deserialize(ValueVisitor)?;
135        Ok(Value::Extended {
136            module: module.to_symbol(),
137            value: Box::new(value),
138        })
139    }
140
141    fn visit_user_class<D>(self, class: &'de Sym, deserializer: D) -> Result<Self::Value>
142    where
143        D: DeserializerTrait<'de>,
144    {
145        let value = deserializer.deserialize(ValueVisitor)?;
146        Ok(Value::UserClass {
147            class: class.to_symbol(),
148            value: Box::new(value),
149        })
150    }
151
152    fn visit_user_data(self, class: &'de Sym, data: &'de [u8]) -> Result<Self::Value> {
153        Ok(Value::Userdata(Userdata {
154            class: class.to_symbol(),
155            data: data.to_vec(),
156        }))
157    }
158
159    fn visit_user_marshal<D>(self, class: &'de Sym, deserializer: D) -> Result<Self::Value>
160    where
161        D: DeserializerTrait<'de>,
162    {
163        let value = deserializer.deserialize(ValueVisitor)?;
164        Ok(Value::UserMarshal {
165            class: class.to_symbol(),
166            value: Box::new(value),
167        })
168    }
169
170    fn visit_data<D>(self, class: &'de Sym, deserializer: D) -> Result<Self::Value>
171    where
172        D: DeserializerTrait<'de>,
173    {
174        let value = deserializer.deserialize(ValueVisitor)?;
175        Ok(Value::Data {
176            class: class.to_symbol(),
177            value: Box::new(value),
178        })
179    }
180}
181
182impl<'de> Deserialize<'de> for Value {
183    fn deserialize<D>(deserializer: D) -> Result<Self>
184    where
185        D: DeserializerTrait<'de>,
186    {
187        deserializer.deserialize(ValueVisitor)
188    }
189}
190
191struct ValueInstanceAccess<'de> {
192    value: &'de Value,
193    fields: &'de RbFields,
194}
195
196struct ValueIVarAccess<'de> {
197    fields: &'de RbFields,
198    index: usize,
199    state: MapState,
200}
201
202struct ValueArrayAccess<'de> {
203    array: &'de [Value],
204    index: usize,
205}
206
207struct ValueHashAccess<'de> {
208    hash: &'de RbHash,
209    index: usize,
210    state: MapState,
211}
212
213enum MapState {
214    Key,
215    Value,
216}
217
218impl<'de> DeserializerTrait<'de> for &'de Value {
219    fn deserialize<V>(self, visitor: V) -> Result<V::Value>
220    where
221        V: Visitor<'de>,
222    {
223        match self {
224            Value::Nil => visitor.visit_nil(),
225            Value::Bool(v) => visitor.visit_bool(*v),
226            Value::Float(f) => visitor.visit_f64(*f),
227            Value::Integer(i) => visitor.visit_i32(*i),
228            Value::String(s) => visitor.visit_string(&s.data),
229            Value::Symbol(s) => visitor.visit_symbol(s),
230            Value::Array(array) => visitor.visit_array(ValueArrayAccess { array, index: 0 }),
231            Value::Hash(hash) => visitor.visit_hash(ValueHashAccess {
232                hash,
233                index: 0,
234                state: MapState::Value, // we want to enforce getting a key next so we set the state to value
235            }),
236            Value::Userdata(u) => visitor.visit_user_data(&u.class, &u.data),
237            Value::Object(o) => visitor.visit_object(
238                &o.class,
239                ValueIVarAccess {
240                    fields: &o.fields,
241                    index: 0,
242                    state: MapState::Value, // we want to enforce getting a key next so we set the state to value
243                },
244            ),
245            Value::Instance(i) => visitor.visit_instance(ValueInstanceAccess {
246                value: &i.value,
247                fields: &i.fields,
248            }),
249            Value::Regex { data, flags } => visitor.visit_regular_expression(&data.data, *flags),
250            Value::RbStruct(s) => visitor.visit_struct(
251                &s.class,
252                ValueIVarAccess {
253                    fields: &s.fields,
254                    index: 0,
255                    state: MapState::Value, // we want to enforce getting a key next so we set the state to value
256                },
257            ),
258            Value::Class(c) => visitor.visit_class(c),
259            Value::Module(m) => visitor.visit_module(m),
260            Value::Extended { module, value } => visitor.visit_extended(module, value.as_ref()),
261            Value::UserClass { class, value } => visitor.visit_user_class(class, value.as_ref()),
262            Value::UserMarshal { class, value } => {
263                visitor.visit_user_marshal(class, value.as_ref())
264            }
265            Value::Data { class, value } => visitor.visit_data(class, value.as_ref()),
266        }
267    }
268
269    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
270    where
271        V: VisitorOption<'de>,
272    {
273        if matches!(self, Value::Nil) {
274            visitor.visit_none()
275        } else {
276            visitor.visit_some(self)
277        }
278    }
279
280    fn deserialize_instance<V>(self, visitor: V) -> Result<V::Value>
281    where
282        V: VisitorInstance<'de>,
283    {
284        if let Value::Instance(i) = self {
285            visitor.visit_instance(ValueInstanceAccess {
286                value: &i.value,
287                fields: &i.fields,
288            })
289        } else {
290            visitor.visit(self)
291        }
292    }
293}
294
295impl<'de> InstanceAccess<'de> for ValueInstanceAccess<'de> {
296    type IvarAccess = ValueIVarAccess<'de>;
297
298    fn value_seed<V>(self, seed: V) -> Result<(V::Value, Self::IvarAccess)>
299    where
300        V: DeserializeSeed<'de>,
301    {
302        let value = seed.deserialize(self.value)?;
303        let access = ValueIVarAccess {
304            fields: self.fields,
305            index: 0,
306            state: MapState::Value, // we want to enforce getting a key next so we set the state to value
307        };
308        Ok((value, access))
309    }
310}
311
312impl<'de> IvarAccess<'de> for ValueIVarAccess<'de> {
313    fn next_ivar(&mut self) -> Result<Option<&'de Sym>> {
314        let Some((field, _)) = self.fields.get_index(self.index) else {
315            return Ok(None);
316        };
317
318        match self.state {
319            MapState::Key => {
320                return Err(Error {
321                    kind: Kind::KeyAfterKey,
322                })
323            }
324            MapState::Value => self.state = MapState::Key,
325        }
326
327        Ok(Some(field))
328    }
329
330    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
331    where
332        V: DeserializeSeed<'de>,
333    {
334        let (_, value) = self.fields.get_index(self.index).ok_or(Error {
335            kind: Kind::ValueAfterValue,
336        })?;
337        self.state = MapState::Value;
338        self.index += 1;
339
340        seed.deserialize(value)
341    }
342
343    fn len(&self) -> usize {
344        self.fields.len()
345    }
346
347    fn index(&self) -> usize {
348        self.index
349    }
350}
351
352impl<'de> ArrayAccess<'de> for ValueArrayAccess<'de> {
353    fn next_element_seed<V>(&mut self, seed: V) -> Result<Option<V::Value>>
354    where
355        V: DeserializeSeed<'de>,
356    {
357        let Some(value) = self.array.get(self.index) else {
358            return Ok(None);
359        };
360        self.index += 1;
361        seed.deserialize(value).map(Some)
362    }
363
364    fn len(&self) -> usize {
365        self.array.len()
366    }
367
368    fn index(&self) -> usize {
369        self.index
370    }
371}
372
373impl<'de> HashAccess<'de> for ValueHashAccess<'de> {
374    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
375    where
376        K: DeserializeSeed<'de>,
377    {
378        let Some((key, _)) = self.hash.get_index(self.index) else {
379            return Ok(None);
380        };
381
382        match self.state {
383            MapState::Key => {
384                return Err(Error {
385                    kind: Kind::KeyAfterKey,
386                })
387            }
388            MapState::Value => self.state = MapState::Key,
389        }
390
391        seed.deserialize(key).map(Some)
392    }
393
394    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
395    where
396        V: DeserializeSeed<'de>,
397    {
398        let (_, value) = self.hash.get_index(self.index).ok_or(Error {
399            kind: Kind::ValueAfterValue,
400        })?;
401        self.state = MapState::Value;
402        self.index += 1;
403
404        seed.deserialize(value)
405    }
406
407    fn len(&self) -> usize {
408        self.hash.len()
409    }
410
411    fn index(&self) -> usize {
412        self.index
413    }
414}