Skip to main content

fidius_guest/
value.rs

1// Copyright 2026 Colliery, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! `Value` — a neutral, self-describing value tree for the plugin boundary.
16//!
17//! Every fidius execution backend dispatches typed method calls through a
18//! single `PluginExecutor::call(method, Value) -> Value` seam (see
19//! `fidius-host`). `Value` is the lingua franca each backend maps to its
20//! native representation:
21//!
22//! - **cdylib**: `Value` → bincode → vtable FFI → bincode → `Value`
23//! - **python**: `Value` → `PyObject` → call → `PyObject` → `Value`
24//! - **wasm**: `Value` → `wasmtime` `component::Val` (Canonical ABI) → `Value`
25//!
26//! The host's generic `call_method<I, O>` stays caller-identical by going
27//! `I → Value` ([`to_value`]) then `Value → O` ([`from_value`]) around the
28//! executor.
29//!
30//! **Layering rule:** `Value` lives in `fidius-core` and is deliberately
31//! free of any backend dependency. Only the WASM executor (Phase 2) maps it
32//! to `wasmtime::component::Val`; cdylib and Python never see wasmtime.
33//!
34//! The variant set mirrors the WebAssembly Component Model value space so the
35//! Phase-2 mapping is mechanical: distinct signed/unsigned integer widths,
36//! `f32`/`f64`, `char`, `string`, `list<u8>` as [`Value::Bytes`], lists,
37//! records, options, and variants.
38
39use std::fmt;
40
41use serde::{de, ser, Deserialize, Serialize};
42
43/// A self-describing value crossing the plugin-call boundary.
44///
45/// Construct one from any `Serialize` type with [`to_value`] and read it back
46/// into any `DeserializeOwned` type with [`from_value`].
47#[derive(Debug, Clone, PartialEq)]
48pub enum Value {
49    /// Boolean.
50    Bool(bool),
51    /// Signed 8-bit integer.
52    S8(i8),
53    /// Signed 16-bit integer.
54    S16(i16),
55    /// Signed 32-bit integer.
56    S32(i32),
57    /// Signed 64-bit integer.
58    S64(i64),
59    /// Unsigned 8-bit integer.
60    U8(u8),
61    /// Unsigned 16-bit integer.
62    U16(u16),
63    /// Unsigned 32-bit integer.
64    U32(u32),
65    /// Unsigned 64-bit integer.
66    U64(u64),
67    /// 32-bit float.
68    F32(f32),
69    /// 64-bit float.
70    F64(f64),
71    /// Unicode scalar value.
72    Char(char),
73    /// UTF-8 string.
74    String(String),
75    /// Opaque byte string (`list<u8>` in WIT terms).
76    Bytes(Vec<u8>),
77    /// Optional value (`none`/`some`).
78    Option(Option<Box<Value>>),
79    /// Ordered sequence — serde seqs, tuples, and tuple structs land here.
80    List(Vec<Value>),
81    /// Named fields — serde structs and string-keyed maps land here.
82    /// Field order is preserved (insertion order).
83    Record(Vec<(String, Value)>),
84    /// General key/value map for non-string keys.
85    Map(Vec<(Value, Value)>),
86    /// A tagged enum case. `value` carries the payload: [`Value::Unit`] for a
87    /// unit variant, the inner value for a newtype variant, a [`Value::List`]
88    /// for a tuple variant, or a [`Value::Record`] for a struct variant.
89    Variant {
90        /// The variant's name.
91        name: String,
92        /// The variant's payload.
93        value: Box<Value>,
94    },
95    /// The unit value — serde `()` and unit structs.
96    Unit,
97}
98
99/// Error produced while converting to or from [`Value`].
100#[derive(Debug, thiserror::Error)]
101#[error("value conversion error: {0}")]
102pub struct ValueError(pub String);
103
104impl ser::Error for ValueError {
105    fn custom<T: fmt::Display>(msg: T) -> Self {
106        ValueError(msg.to_string())
107    }
108}
109
110impl de::Error for ValueError {
111    fn custom<T: fmt::Display>(msg: T) -> Self {
112        ValueError(msg.to_string())
113    }
114}
115
116/// Convert any [`Serialize`] type into a [`Value`].
117pub fn to_value<T: Serialize>(value: &T) -> Result<Value, ValueError> {
118    value.serialize(ValueSerializer)
119}
120
121/// Convert a [`Value`] into any [`Deserialize`] type.
122pub fn from_value<T>(value: Value) -> Result<T, ValueError>
123where
124    T: de::DeserializeOwned,
125{
126    T::deserialize(value)
127}
128
129// ===========================================================================
130// Serializer: T -> Value
131// ===========================================================================
132
133struct ValueSerializer;
134
135impl ser::Serializer for ValueSerializer {
136    type Ok = Value;
137    type Error = ValueError;
138
139    type SerializeSeq = SeqSerializer;
140    type SerializeTuple = SeqSerializer;
141    type SerializeTupleStruct = SeqSerializer;
142    type SerializeTupleVariant = TupleVariantSerializer;
143    type SerializeMap = MapSerializer;
144    type SerializeStruct = StructSerializer;
145    type SerializeStructVariant = StructVariantSerializer;
146
147    fn serialize_bool(self, v: bool) -> Result<Value, ValueError> {
148        Ok(Value::Bool(v))
149    }
150    fn serialize_i8(self, v: i8) -> Result<Value, ValueError> {
151        Ok(Value::S8(v))
152    }
153    fn serialize_i16(self, v: i16) -> Result<Value, ValueError> {
154        Ok(Value::S16(v))
155    }
156    fn serialize_i32(self, v: i32) -> Result<Value, ValueError> {
157        Ok(Value::S32(v))
158    }
159    fn serialize_i64(self, v: i64) -> Result<Value, ValueError> {
160        Ok(Value::S64(v))
161    }
162    fn serialize_u8(self, v: u8) -> Result<Value, ValueError> {
163        Ok(Value::U8(v))
164    }
165    fn serialize_u16(self, v: u16) -> Result<Value, ValueError> {
166        Ok(Value::U16(v))
167    }
168    fn serialize_u32(self, v: u32) -> Result<Value, ValueError> {
169        Ok(Value::U32(v))
170    }
171    fn serialize_u64(self, v: u64) -> Result<Value, ValueError> {
172        Ok(Value::U64(v))
173    }
174    fn serialize_f32(self, v: f32) -> Result<Value, ValueError> {
175        Ok(Value::F32(v))
176    }
177    fn serialize_f64(self, v: f64) -> Result<Value, ValueError> {
178        Ok(Value::F64(v))
179    }
180    fn serialize_char(self, v: char) -> Result<Value, ValueError> {
181        Ok(Value::Char(v))
182    }
183    fn serialize_str(self, v: &str) -> Result<Value, ValueError> {
184        Ok(Value::String(v.to_string()))
185    }
186    fn serialize_bytes(self, v: &[u8]) -> Result<Value, ValueError> {
187        Ok(Value::Bytes(v.to_vec()))
188    }
189    fn serialize_none(self) -> Result<Value, ValueError> {
190        Ok(Value::Option(None))
191    }
192    fn serialize_some<T>(self, value: &T) -> Result<Value, ValueError>
193    where
194        T: ?Sized + Serialize,
195    {
196        Ok(Value::Option(Some(Box::new(
197            value.serialize(ValueSerializer)?,
198        ))))
199    }
200    fn serialize_unit(self) -> Result<Value, ValueError> {
201        Ok(Value::Unit)
202    }
203    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, ValueError> {
204        Ok(Value::Unit)
205    }
206    fn serialize_unit_variant(
207        self,
208        _name: &'static str,
209        _variant_index: u32,
210        variant: &'static str,
211    ) -> Result<Value, ValueError> {
212        Ok(Value::Variant {
213            name: variant.to_string(),
214            value: Box::new(Value::Unit),
215        })
216    }
217    fn serialize_newtype_struct<T>(
218        self,
219        _name: &'static str,
220        value: &T,
221    ) -> Result<Value, ValueError>
222    where
223        T: ?Sized + Serialize,
224    {
225        value.serialize(ValueSerializer)
226    }
227    fn serialize_newtype_variant<T>(
228        self,
229        _name: &'static str,
230        _variant_index: u32,
231        variant: &'static str,
232        value: &T,
233    ) -> Result<Value, ValueError>
234    where
235        T: ?Sized + Serialize,
236    {
237        Ok(Value::Variant {
238            name: variant.to_string(),
239            value: Box::new(value.serialize(ValueSerializer)?),
240        })
241    }
242    fn serialize_seq(self, len: Option<usize>) -> Result<SeqSerializer, ValueError> {
243        Ok(SeqSerializer {
244            items: Vec::with_capacity(len.unwrap_or(0)),
245        })
246    }
247    fn serialize_tuple(self, len: usize) -> Result<SeqSerializer, ValueError> {
248        self.serialize_seq(Some(len))
249    }
250    fn serialize_tuple_struct(
251        self,
252        _name: &'static str,
253        len: usize,
254    ) -> Result<SeqSerializer, ValueError> {
255        self.serialize_seq(Some(len))
256    }
257    fn serialize_tuple_variant(
258        self,
259        _name: &'static str,
260        _variant_index: u32,
261        variant: &'static str,
262        len: usize,
263    ) -> Result<TupleVariantSerializer, ValueError> {
264        Ok(TupleVariantSerializer {
265            name: variant.to_string(),
266            items: Vec::with_capacity(len),
267        })
268    }
269    fn serialize_map(self, _len: Option<usize>) -> Result<MapSerializer, ValueError> {
270        Ok(MapSerializer {
271            entries: Vec::new(),
272            next_key: None,
273        })
274    }
275    fn serialize_struct(
276        self,
277        _name: &'static str,
278        len: usize,
279    ) -> Result<StructSerializer, ValueError> {
280        Ok(StructSerializer {
281            fields: Vec::with_capacity(len),
282        })
283    }
284    fn serialize_struct_variant(
285        self,
286        _name: &'static str,
287        _variant_index: u32,
288        variant: &'static str,
289        len: usize,
290    ) -> Result<StructVariantSerializer, ValueError> {
291        Ok(StructVariantSerializer {
292            name: variant.to_string(),
293            fields: Vec::with_capacity(len),
294        })
295    }
296}
297
298struct SeqSerializer {
299    items: Vec<Value>,
300}
301impl ser::SerializeSeq for SeqSerializer {
302    type Ok = Value;
303    type Error = ValueError;
304    fn serialize_element<T>(&mut self, value: &T) -> Result<(), ValueError>
305    where
306        T: ?Sized + Serialize,
307    {
308        self.items.push(value.serialize(ValueSerializer)?);
309        Ok(())
310    }
311    fn end(self) -> Result<Value, ValueError> {
312        Ok(Value::List(self.items))
313    }
314}
315impl ser::SerializeTuple for SeqSerializer {
316    type Ok = Value;
317    type Error = ValueError;
318    fn serialize_element<T>(&mut self, value: &T) -> Result<(), ValueError>
319    where
320        T: ?Sized + Serialize,
321    {
322        ser::SerializeSeq::serialize_element(self, value)
323    }
324    fn end(self) -> Result<Value, ValueError> {
325        ser::SerializeSeq::end(self)
326    }
327}
328impl ser::SerializeTupleStruct for SeqSerializer {
329    type Ok = Value;
330    type Error = ValueError;
331    fn serialize_field<T>(&mut self, value: &T) -> Result<(), ValueError>
332    where
333        T: ?Sized + Serialize,
334    {
335        ser::SerializeSeq::serialize_element(self, value)
336    }
337    fn end(self) -> Result<Value, ValueError> {
338        ser::SerializeSeq::end(self)
339    }
340}
341
342struct TupleVariantSerializer {
343    name: String,
344    items: Vec<Value>,
345}
346impl ser::SerializeTupleVariant for TupleVariantSerializer {
347    type Ok = Value;
348    type Error = ValueError;
349    fn serialize_field<T>(&mut self, value: &T) -> Result<(), ValueError>
350    where
351        T: ?Sized + Serialize,
352    {
353        self.items.push(value.serialize(ValueSerializer)?);
354        Ok(())
355    }
356    fn end(self) -> Result<Value, ValueError> {
357        Ok(Value::Variant {
358            name: self.name,
359            value: Box::new(Value::List(self.items)),
360        })
361    }
362}
363
364struct MapSerializer {
365    entries: Vec<(Value, Value)>,
366    next_key: Option<Value>,
367}
368impl ser::SerializeMap for MapSerializer {
369    type Ok = Value;
370    type Error = ValueError;
371    fn serialize_key<T>(&mut self, key: &T) -> Result<(), ValueError>
372    where
373        T: ?Sized + Serialize,
374    {
375        self.next_key = Some(key.serialize(ValueSerializer)?);
376        Ok(())
377    }
378    fn serialize_value<T>(&mut self, value: &T) -> Result<(), ValueError>
379    where
380        T: ?Sized + Serialize,
381    {
382        let key = self
383            .next_key
384            .take()
385            .ok_or_else(|| ValueError("serialize_value called before serialize_key".into()))?;
386        self.entries.push((key, value.serialize(ValueSerializer)?));
387        Ok(())
388    }
389    fn end(self) -> Result<Value, ValueError> {
390        // If every key is a string, prefer a Record so round-tripping into
391        // structs (and the Python/JSON bridges) is natural.
392        if self
393            .entries
394            .iter()
395            .all(|(k, _)| matches!(k, Value::String(_)))
396        {
397            let fields = self
398                .entries
399                .into_iter()
400                .map(|(k, v)| match k {
401                    Value::String(s) => (s, v),
402                    _ => unreachable!(),
403                })
404                .collect();
405            Ok(Value::Record(fields))
406        } else {
407            Ok(Value::Map(self.entries))
408        }
409    }
410}
411
412struct StructSerializer {
413    fields: Vec<(String, Value)>,
414}
415impl ser::SerializeStruct for StructSerializer {
416    type Ok = Value;
417    type Error = ValueError;
418    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), ValueError>
419    where
420        T: ?Sized + Serialize,
421    {
422        self.fields
423            .push((key.to_string(), value.serialize(ValueSerializer)?));
424        Ok(())
425    }
426    fn end(self) -> Result<Value, ValueError> {
427        Ok(Value::Record(self.fields))
428    }
429}
430
431struct StructVariantSerializer {
432    name: String,
433    fields: Vec<(String, Value)>,
434}
435impl ser::SerializeStructVariant for StructVariantSerializer {
436    type Ok = Value;
437    type Error = ValueError;
438    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), ValueError>
439    where
440        T: ?Sized + Serialize,
441    {
442        self.fields
443            .push((key.to_string(), value.serialize(ValueSerializer)?));
444        Ok(())
445    }
446    fn end(self) -> Result<Value, ValueError> {
447        Ok(Value::Variant {
448            name: self.name,
449            value: Box::new(Value::Record(self.fields)),
450        })
451    }
452}
453
454// ===========================================================================
455// Deserializer: Value -> T
456// ===========================================================================
457
458impl<'de> de::Deserializer<'de> for Value {
459    type Error = ValueError;
460
461    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, ValueError>
462    where
463        V: de::Visitor<'de>,
464    {
465        match self {
466            Value::Bool(b) => visitor.visit_bool(b),
467            Value::S8(v) => visitor.visit_i8(v),
468            Value::S16(v) => visitor.visit_i16(v),
469            Value::S32(v) => visitor.visit_i32(v),
470            Value::S64(v) => visitor.visit_i64(v),
471            Value::U8(v) => visitor.visit_u8(v),
472            Value::U16(v) => visitor.visit_u16(v),
473            Value::U32(v) => visitor.visit_u32(v),
474            Value::U64(v) => visitor.visit_u64(v),
475            Value::F32(v) => visitor.visit_f32(v),
476            Value::F64(v) => visitor.visit_f64(v),
477            Value::Char(v) => visitor.visit_char(v),
478            Value::String(s) => visitor.visit_string(s),
479            Value::Bytes(b) => visitor.visit_byte_buf(b),
480            Value::Unit => visitor.visit_unit(),
481            Value::Option(None) => visitor.visit_none(),
482            Value::Option(Some(v)) => visitor.visit_some(*v),
483            Value::List(items) => visitor.visit_seq(SeqAccess {
484                iter: items.into_iter(),
485            }),
486            Value::Record(fields) => visitor.visit_map(RecordAccess {
487                iter: fields.into_iter(),
488                value: None,
489            }),
490            Value::Map(entries) => visitor.visit_map(MapAccess {
491                iter: entries.into_iter(),
492                value: None,
493            }),
494            Value::Variant { name, value } => visitor.visit_map(SingletonMapAccess {
495                key: Some(name),
496                value: Some(*value),
497            }),
498        }
499    }
500
501    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, ValueError>
502    where
503        V: de::Visitor<'de>,
504    {
505        match self {
506            Value::Option(None) => visitor.visit_none(),
507            Value::Option(Some(v)) => visitor.visit_some(*v),
508            other => visitor.visit_some(other),
509        }
510    }
511
512    fn deserialize_enum<V>(
513        self,
514        _name: &'static str,
515        _variants: &'static [&'static str],
516        visitor: V,
517    ) -> Result<V::Value, ValueError>
518    where
519        V: de::Visitor<'de>,
520    {
521        match self {
522            // `EnumName::Variant` with no payload may serialize as a bare
523            // string in some formats; accept that too.
524            Value::String(s) => visitor.visit_enum(EnumAccess {
525                name: s,
526                value: Value::Unit,
527            }),
528            Value::Variant { name, value } => visitor.visit_enum(EnumAccess {
529                name,
530                value: *value,
531            }),
532            other => Err(ValueError(format!(
533                "expected enum variant, found {}",
534                other.kind()
535            ))),
536        }
537    }
538
539    fn deserialize_newtype_struct<V>(
540        self,
541        _name: &'static str,
542        visitor: V,
543    ) -> Result<V::Value, ValueError>
544    where
545        V: de::Visitor<'de>,
546    {
547        visitor.visit_newtype_struct(self)
548    }
549
550    fn deserialize_unit_struct<V>(
551        self,
552        _name: &'static str,
553        visitor: V,
554    ) -> Result<V::Value, ValueError>
555    where
556        V: de::Visitor<'de>,
557    {
558        self.deserialize_unit(visitor)
559    }
560
561    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, ValueError>
562    where
563        V: de::Visitor<'de>,
564    {
565        match self {
566            Value::Unit => visitor.visit_unit(),
567            // An empty tuple/list also reads as unit.
568            Value::List(items) if items.is_empty() => visitor.visit_unit(),
569            other => Err(ValueError(format!("expected unit, found {}", other.kind()))),
570        }
571    }
572
573    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, ValueError>
574    where
575        V: de::Visitor<'de>,
576    {
577        match self {
578            Value::Map(entries) => visitor.visit_map(MapAccess {
579                iter: entries.into_iter(),
580                value: None,
581            }),
582            Value::Record(fields) => visitor.visit_map(RecordAccess {
583                iter: fields.into_iter(),
584                value: None,
585            }),
586            // A map projected across the WASM boundary arrives as `list<tuple<k, v>>`
587            // — a `Value::List` of 2-element pairs. Accept it as a map so
588            // `HashMap`/`BTreeMap` round-trips (PC.1). `Vec<(K, V)>` still reads the
589            // same value via `deserialize_seq`.
590            Value::List(items) => {
591                let mut entries = Vec::with_capacity(items.len());
592                for it in items {
593                    match it {
594                        Value::List(mut kv) if kv.len() == 2 => {
595                            let v = kv.pop().unwrap();
596                            let k = kv.pop().unwrap();
597                            entries.push((k, v));
598                        }
599                        other => {
600                            return Err(ValueError(format!(
601                                "expected a [key, value] pair reading a map from a list, found {}",
602                                other.kind()
603                            )))
604                        }
605                    }
606                }
607                visitor.visit_map(MapAccess {
608                    iter: entries.into_iter(),
609                    value: None,
610                })
611            }
612            other => Err(ValueError(format!("expected map, found {}", other.kind()))),
613        }
614    }
615
616    serde::forward_to_deserialize_any! {
617        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
618        bytes byte_buf seq tuple tuple_struct struct identifier
619        ignored_any
620    }
621}
622
623impl Value {
624    fn kind(&self) -> &'static str {
625        match self {
626            Value::Bool(_) => "bool",
627            Value::S8(_) | Value::S16(_) | Value::S32(_) | Value::S64(_) => "signed integer",
628            Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => "unsigned integer",
629            Value::F32(_) | Value::F64(_) => "float",
630            Value::Char(_) => "char",
631            Value::String(_) => "string",
632            Value::Bytes(_) => "bytes",
633            Value::Option(_) => "option",
634            Value::List(_) => "list",
635            Value::Record(_) => "record",
636            Value::Map(_) => "map",
637            Value::Variant { .. } => "variant",
638            Value::Unit => "unit",
639        }
640    }
641}
642
643struct SeqAccess {
644    iter: std::vec::IntoIter<Value>,
645}
646impl<'de> de::SeqAccess<'de> for SeqAccess {
647    type Error = ValueError;
648    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, ValueError>
649    where
650        T: de::DeserializeSeed<'de>,
651    {
652        match self.iter.next() {
653            Some(v) => seed.deserialize(v).map(Some),
654            None => Ok(None),
655        }
656    }
657    fn size_hint(&self) -> Option<usize> {
658        Some(self.iter.len())
659    }
660}
661
662struct RecordAccess {
663    iter: std::vec::IntoIter<(String, Value)>,
664    value: Option<Value>,
665}
666impl<'de> de::MapAccess<'de> for RecordAccess {
667    type Error = ValueError;
668    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, ValueError>
669    where
670        K: de::DeserializeSeed<'de>,
671    {
672        match self.iter.next() {
673            Some((k, v)) => {
674                self.value = Some(v);
675                seed.deserialize(Value::String(k)).map(Some)
676            }
677            None => Ok(None),
678        }
679    }
680    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, ValueError>
681    where
682        V: de::DeserializeSeed<'de>,
683    {
684        let v = self
685            .value
686            .take()
687            .ok_or_else(|| ValueError("next_value called before next_key".into()))?;
688        seed.deserialize(v)
689    }
690    fn size_hint(&self) -> Option<usize> {
691        Some(self.iter.len())
692    }
693}
694
695struct MapAccess {
696    iter: std::vec::IntoIter<(Value, Value)>,
697    value: Option<Value>,
698}
699impl<'de> de::MapAccess<'de> for MapAccess {
700    type Error = ValueError;
701    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, ValueError>
702    where
703        K: de::DeserializeSeed<'de>,
704    {
705        match self.iter.next() {
706            Some((k, v)) => {
707                self.value = Some(v);
708                seed.deserialize(k).map(Some)
709            }
710            None => Ok(None),
711        }
712    }
713    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, ValueError>
714    where
715        V: de::DeserializeSeed<'de>,
716    {
717        let v = self
718            .value
719            .take()
720            .ok_or_else(|| ValueError("next_value called before next_key".into()))?;
721        seed.deserialize(v)
722    }
723    fn size_hint(&self) -> Option<usize> {
724        Some(self.iter.len())
725    }
726}
727
728/// Presents a `Value::Variant` as a single-entry map for `deserialize_any`
729/// consumers (e.g. deserializing into `serde_json::Value`).
730struct SingletonMapAccess {
731    key: Option<String>,
732    value: Option<Value>,
733}
734impl<'de> de::MapAccess<'de> for SingletonMapAccess {
735    type Error = ValueError;
736    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, ValueError>
737    where
738        K: de::DeserializeSeed<'de>,
739    {
740        match self.key.take() {
741            Some(k) => seed.deserialize(Value::String(k)).map(Some),
742            None => Ok(None),
743        }
744    }
745    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, ValueError>
746    where
747        V: de::DeserializeSeed<'de>,
748    {
749        let v = self
750            .value
751            .take()
752            .ok_or_else(|| ValueError("variant value already consumed".into()))?;
753        seed.deserialize(v)
754    }
755}
756
757struct EnumAccess {
758    name: String,
759    value: Value,
760}
761impl<'de> de::EnumAccess<'de> for EnumAccess {
762    type Error = ValueError;
763    type Variant = VariantAccess;
764    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantAccess), ValueError>
765    where
766        V: de::DeserializeSeed<'de>,
767    {
768        let variant = seed.deserialize(Value::String(self.name))?;
769        Ok((variant, VariantAccess { value: self.value }))
770    }
771}
772
773struct VariantAccess {
774    value: Value,
775}
776impl<'de> de::VariantAccess<'de> for VariantAccess {
777    type Error = ValueError;
778    fn unit_variant(self) -> Result<(), ValueError> {
779        match self.value {
780            Value::Unit => Ok(()),
781            other => Err(ValueError(format!(
782                "expected unit variant, found {}",
783                other.kind()
784            ))),
785        }
786    }
787    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, ValueError>
788    where
789        T: de::DeserializeSeed<'de>,
790    {
791        seed.deserialize(self.value)
792    }
793    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, ValueError>
794    where
795        V: de::Visitor<'de>,
796    {
797        match self.value {
798            Value::List(items) => visitor.visit_seq(SeqAccess {
799                iter: items.into_iter(),
800            }),
801            other => Err(ValueError(format!(
802                "expected tuple variant, found {}",
803                other.kind()
804            ))),
805        }
806    }
807    fn struct_variant<V>(
808        self,
809        _fields: &'static [&'static str],
810        visitor: V,
811    ) -> Result<V::Value, ValueError>
812    where
813        V: de::Visitor<'de>,
814    {
815        match self.value {
816            Value::Record(fields) => visitor.visit_map(RecordAccess {
817                iter: fields.into_iter(),
818                value: None,
819            }),
820            other => Err(ValueError(format!(
821                "expected struct variant, found {}",
822                other.kind()
823            ))),
824        }
825    }
826}
827
828#[cfg(test)]
829mod tests {
830    use super::*;
831    use serde::{Deserialize, Serialize};
832
833    fn round_trip<T>(value: T)
834    where
835        T: Serialize + de::DeserializeOwned + PartialEq + fmt::Debug + Clone,
836    {
837        let v = to_value(&value).expect("to_value");
838        let back: T = from_value(v).expect("from_value");
839        assert_eq!(back, value);
840    }
841
842    #[test]
843    fn map_deserializes_from_a_list_of_pairs() {
844        use std::collections::HashMap;
845        // PC.1: a map crosses the WASM boundary as `list<tuple<k,v>>`, i.e. a
846        // `Value::List` of 2-element pairs. It must deserialize into a `HashMap`...
847        let pairs = Value::List(vec![
848            Value::List(vec![Value::String("a".into()), Value::U32(1)]),
849            Value::List(vec![Value::String("b".into()), Value::U32(2)]),
850        ]);
851        let m: HashMap<String, u32> = from_value(pairs.clone()).expect("list-of-pairs → map");
852        assert_eq!(m.get("a"), Some(&1));
853        assert_eq!(m.get("b"), Some(&2));
854        // ...and the same value still reads as a `Vec<(K, V)>`.
855        let v: Vec<(String, u32)> = from_value(pairs).expect("list-of-pairs → vec");
856        assert_eq!(v.len(), 2);
857        // A non-string-keyed map also round-trips (via Value::Map).
858        let mut nk: HashMap<u32, String> = HashMap::new();
859        nk.insert(7, "seven".into());
860        round_trip(nk);
861    }
862
863    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
864    struct Greeting {
865        name: String,
866        times: u32,
867        loud: bool,
868    }
869
870    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
871    struct Wrapper(u64);
872
873    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
874    enum Shape {
875        Unit,
876        Newtype(i32),
877        Tuple(i32, i32),
878        Struct { w: u16, h: u16 },
879    }
880
881    #[test]
882    fn primitives() {
883        round_trip(true);
884        round_trip(-5i8);
885        round_trip(40000u16);
886        round_trip(u64::MAX);
887        round_trip(i64::MIN);
888        round_trip(3.5f32);
889        round_trip(2.718281828f64);
890        round_trip('λ');
891        round_trip("hello".to_string());
892    }
893
894    #[test]
895    fn collections() {
896        round_trip(vec![1i32, 2, 3]);
897        round_trip(Some(7u8));
898        round_trip(Option::<u8>::None);
899        round_trip((1i32, "two".to_string(), false));
900        round_trip(vec![Some(1u32), None, Some(3)]);
901    }
902
903    #[test]
904    fn structs_and_maps() {
905        round_trip(Greeting {
906            name: "ada".to_string(),
907            times: 3,
908            loud: true,
909        });
910        round_trip(Wrapper(99));
911
912        use std::collections::BTreeMap;
913        let mut m = BTreeMap::new();
914        m.insert("a".to_string(), 1i32);
915        m.insert("b".to_string(), 2);
916        round_trip(m);
917
918        let mut numkeys = BTreeMap::new();
919        numkeys.insert(1u32, "one".to_string());
920        numkeys.insert(2u32, "two".to_string());
921        round_trip(numkeys);
922    }
923
924    #[test]
925    fn enums() {
926        round_trip(Shape::Unit);
927        round_trip(Shape::Newtype(-9));
928        round_trip(Shape::Tuple(3, 4));
929        round_trip(Shape::Struct { w: 10, h: 20 });
930    }
931
932    #[test]
933    fn nested() {
934        #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
935        struct Outer {
936            shapes: Vec<Shape>,
937            tag: Option<String>,
938        }
939        round_trip(Outer {
940            shapes: vec![Shape::Unit, Shape::Tuple(1, 2), Shape::Newtype(5)],
941            tag: Some("x".to_string()),
942        });
943    }
944
945    #[test]
946    fn struct_shape_is_record() {
947        let v = to_value(&Greeting {
948            name: "z".into(),
949            times: 1,
950            loud: false,
951        })
952        .unwrap();
953        match v {
954            Value::Record(fields) => {
955                assert_eq!(fields[0].0, "name");
956                assert_eq!(fields[1].0, "times");
957                assert_eq!(fields[2].0, "loud");
958            }
959            other => panic!("expected record, got {other:?}"),
960        }
961    }
962}
963
964// `Value` is itself serde-serializable so it can be embedded in other
965// structures and round-tripped through any format when needed.
966impl Serialize for Value {
967    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
968    where
969        S: ser::Serializer,
970    {
971        match self {
972            Value::Bool(v) => serializer.serialize_bool(*v),
973            Value::S8(v) => serializer.serialize_i8(*v),
974            Value::S16(v) => serializer.serialize_i16(*v),
975            Value::S32(v) => serializer.serialize_i32(*v),
976            Value::S64(v) => serializer.serialize_i64(*v),
977            Value::U8(v) => serializer.serialize_u8(*v),
978            Value::U16(v) => serializer.serialize_u16(*v),
979            Value::U32(v) => serializer.serialize_u32(*v),
980            Value::U64(v) => serializer.serialize_u64(*v),
981            Value::F32(v) => serializer.serialize_f32(*v),
982            Value::F64(v) => serializer.serialize_f64(*v),
983            Value::Char(v) => serializer.serialize_char(*v),
984            Value::String(v) => serializer.serialize_str(v),
985            Value::Bytes(v) => serializer.serialize_bytes(v),
986            Value::Unit => serializer.serialize_unit(),
987            Value::Option(None) => serializer.serialize_none(),
988            Value::Option(Some(v)) => serializer.serialize_some(v),
989            Value::List(items) => {
990                use ser::SerializeSeq;
991                let mut seq = serializer.serialize_seq(Some(items.len()))?;
992                for item in items {
993                    seq.serialize_element(item)?;
994                }
995                seq.end()
996            }
997            Value::Record(fields) => {
998                use ser::SerializeMap;
999                let mut map = serializer.serialize_map(Some(fields.len()))?;
1000                for (k, v) in fields {
1001                    map.serialize_entry(k, v)?;
1002                }
1003                map.end()
1004            }
1005            Value::Map(entries) => {
1006                use ser::SerializeMap;
1007                let mut map = serializer.serialize_map(Some(entries.len()))?;
1008                for (k, v) in entries {
1009                    map.serialize_entry(k, v)?;
1010                }
1011                map.end()
1012            }
1013            Value::Variant { name, value } => {
1014                use ser::SerializeMap;
1015                let mut map = serializer.serialize_map(Some(1))?;
1016                map.serialize_entry(name, value)?;
1017                map.end()
1018            }
1019        }
1020    }
1021}
1022
1023impl<'de> Deserialize<'de> for Value {
1024    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
1025    where
1026        D: de::Deserializer<'de>,
1027    {
1028        struct ValueVisitor;
1029        impl<'de> de::Visitor<'de> for ValueVisitor {
1030            type Value = Value;
1031            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1032                f.write_str("any fidius value")
1033            }
1034            fn visit_bool<E>(self, v: bool) -> Result<Value, E> {
1035                Ok(Value::Bool(v))
1036            }
1037            fn visit_i64<E>(self, v: i64) -> Result<Value, E> {
1038                Ok(Value::S64(v))
1039            }
1040            fn visit_i128<E>(self, v: i128) -> Result<Value, E>
1041            where
1042                E: de::Error,
1043            {
1044                i64::try_from(v)
1045                    .map(Value::S64)
1046                    .map_err(|_| E::custom("i128 out of range"))
1047            }
1048            fn visit_u64<E>(self, v: u64) -> Result<Value, E> {
1049                Ok(Value::U64(v))
1050            }
1051            fn visit_u128<E>(self, v: u128) -> Result<Value, E>
1052            where
1053                E: de::Error,
1054            {
1055                u64::try_from(v)
1056                    .map(Value::U64)
1057                    .map_err(|_| E::custom("u128 out of range"))
1058            }
1059            fn visit_f64<E>(self, v: f64) -> Result<Value, E> {
1060                Ok(Value::F64(v))
1061            }
1062            fn visit_char<E>(self, v: char) -> Result<Value, E> {
1063                Ok(Value::Char(v))
1064            }
1065            fn visit_str<E>(self, v: &str) -> Result<Value, E> {
1066                Ok(Value::String(v.to_string()))
1067            }
1068            fn visit_string<E>(self, v: String) -> Result<Value, E> {
1069                Ok(Value::String(v))
1070            }
1071            fn visit_bytes<E>(self, v: &[u8]) -> Result<Value, E> {
1072                Ok(Value::Bytes(v.to_vec()))
1073            }
1074            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Value, E> {
1075                Ok(Value::Bytes(v))
1076            }
1077            fn visit_unit<E>(self) -> Result<Value, E> {
1078                Ok(Value::Unit)
1079            }
1080            fn visit_none<E>(self) -> Result<Value, E> {
1081                Ok(Value::Option(None))
1082            }
1083            fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
1084            where
1085                D: de::Deserializer<'de>,
1086            {
1087                Ok(Value::Option(Some(Box::new(Value::deserialize(
1088                    deserializer,
1089                )?))))
1090            }
1091            fn visit_seq<A>(self, mut seq: A) -> Result<Value, A::Error>
1092            where
1093                A: de::SeqAccess<'de>,
1094            {
1095                let mut items = Vec::new();
1096                while let Some(v) = seq.next_element()? {
1097                    items.push(v);
1098                }
1099                Ok(Value::List(items))
1100            }
1101            fn visit_map<A>(self, mut map: A) -> Result<Value, A::Error>
1102            where
1103                A: de::MapAccess<'de>,
1104            {
1105                let mut fields = Vec::new();
1106                while let Some((k, v)) = map.next_entry::<String, Value>()? {
1107                    fields.push((k, v));
1108                }
1109                Ok(Value::Record(fields))
1110            }
1111        }
1112        deserializer.deserialize_any(ValueVisitor)
1113    }
1114}