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// `Value` is itself serde-serializable so it can be embedded in other
829// structures and round-tripped through any format when needed.
830impl Serialize for Value {
831    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
832    where
833        S: ser::Serializer,
834    {
835        match self {
836            Value::Bool(v) => serializer.serialize_bool(*v),
837            Value::S8(v) => serializer.serialize_i8(*v),
838            Value::S16(v) => serializer.serialize_i16(*v),
839            Value::S32(v) => serializer.serialize_i32(*v),
840            Value::S64(v) => serializer.serialize_i64(*v),
841            Value::U8(v) => serializer.serialize_u8(*v),
842            Value::U16(v) => serializer.serialize_u16(*v),
843            Value::U32(v) => serializer.serialize_u32(*v),
844            Value::U64(v) => serializer.serialize_u64(*v),
845            Value::F32(v) => serializer.serialize_f32(*v),
846            Value::F64(v) => serializer.serialize_f64(*v),
847            Value::Char(v) => serializer.serialize_char(*v),
848            Value::String(v) => serializer.serialize_str(v),
849            Value::Bytes(v) => serializer.serialize_bytes(v),
850            Value::Unit => serializer.serialize_unit(),
851            Value::Option(None) => serializer.serialize_none(),
852            Value::Option(Some(v)) => serializer.serialize_some(v),
853            Value::List(items) => {
854                use ser::SerializeSeq;
855                let mut seq = serializer.serialize_seq(Some(items.len()))?;
856                for item in items {
857                    seq.serialize_element(item)?;
858                }
859                seq.end()
860            }
861            Value::Record(fields) => {
862                use ser::SerializeMap;
863                let mut map = serializer.serialize_map(Some(fields.len()))?;
864                for (k, v) in fields {
865                    map.serialize_entry(k, v)?;
866                }
867                map.end()
868            }
869            Value::Map(entries) => {
870                use ser::SerializeMap;
871                let mut map = serializer.serialize_map(Some(entries.len()))?;
872                for (k, v) in entries {
873                    map.serialize_entry(k, v)?;
874                }
875                map.end()
876            }
877            Value::Variant { name, value } => {
878                use ser::SerializeMap;
879                let mut map = serializer.serialize_map(Some(1))?;
880                map.serialize_entry(name, value)?;
881                map.end()
882            }
883        }
884    }
885}
886
887impl<'de> Deserialize<'de> for Value {
888    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
889    where
890        D: de::Deserializer<'de>,
891    {
892        struct ValueVisitor;
893        impl<'de> de::Visitor<'de> for ValueVisitor {
894            type Value = Value;
895            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
896                f.write_str("any fidius value")
897            }
898            fn visit_bool<E>(self, v: bool) -> Result<Value, E> {
899                Ok(Value::Bool(v))
900            }
901            fn visit_i64<E>(self, v: i64) -> Result<Value, E> {
902                Ok(Value::S64(v))
903            }
904            fn visit_i128<E>(self, v: i128) -> Result<Value, E>
905            where
906                E: de::Error,
907            {
908                i64::try_from(v)
909                    .map(Value::S64)
910                    .map_err(|_| E::custom("i128 out of range"))
911            }
912            fn visit_u64<E>(self, v: u64) -> Result<Value, E> {
913                Ok(Value::U64(v))
914            }
915            fn visit_u128<E>(self, v: u128) -> Result<Value, E>
916            where
917                E: de::Error,
918            {
919                u64::try_from(v)
920                    .map(Value::U64)
921                    .map_err(|_| E::custom("u128 out of range"))
922            }
923            fn visit_f64<E>(self, v: f64) -> Result<Value, E> {
924                Ok(Value::F64(v))
925            }
926            fn visit_char<E>(self, v: char) -> Result<Value, E> {
927                Ok(Value::Char(v))
928            }
929            fn visit_str<E>(self, v: &str) -> Result<Value, E> {
930                Ok(Value::String(v.to_string()))
931            }
932            fn visit_string<E>(self, v: String) -> Result<Value, E> {
933                Ok(Value::String(v))
934            }
935            fn visit_bytes<E>(self, v: &[u8]) -> Result<Value, E> {
936                Ok(Value::Bytes(v.to_vec()))
937            }
938            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Value, E> {
939                Ok(Value::Bytes(v))
940            }
941            fn visit_unit<E>(self) -> Result<Value, E> {
942                Ok(Value::Unit)
943            }
944            fn visit_none<E>(self) -> Result<Value, E> {
945                Ok(Value::Option(None))
946            }
947            fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
948            where
949                D: de::Deserializer<'de>,
950            {
951                Ok(Value::Option(Some(Box::new(Value::deserialize(
952                    deserializer,
953                )?))))
954            }
955            fn visit_seq<A>(self, mut seq: A) -> Result<Value, A::Error>
956            where
957                A: de::SeqAccess<'de>,
958            {
959                let mut items = Vec::new();
960                while let Some(v) = seq.next_element()? {
961                    items.push(v);
962                }
963                Ok(Value::List(items))
964            }
965            fn visit_map<A>(self, mut map: A) -> Result<Value, A::Error>
966            where
967                A: de::MapAccess<'de>,
968            {
969                let mut fields = Vec::new();
970                while let Some((k, v)) = map.next_entry::<String, Value>()? {
971                    fields.push((k, v));
972                }
973                Ok(Value::Record(fields))
974            }
975        }
976        deserializer.deserialize_any(ValueVisitor)
977    }
978}
979
980#[cfg(test)]
981mod tests {
982    use super::*;
983    use serde::{Deserialize, Serialize};
984
985    fn round_trip<T>(value: T)
986    where
987        T: Serialize + de::DeserializeOwned + PartialEq + fmt::Debug + Clone,
988    {
989        let v = to_value(&value).expect("to_value");
990        let back: T = from_value(v).expect("from_value");
991        assert_eq!(back, value);
992    }
993
994    #[test]
995    fn map_deserializes_from_a_list_of_pairs() {
996        use std::collections::HashMap;
997        // PC.1: a map crosses the WASM boundary as `list<tuple<k,v>>`, i.e. a
998        // `Value::List` of 2-element pairs. It must deserialize into a `HashMap`...
999        let pairs = Value::List(vec![
1000            Value::List(vec![Value::String("a".into()), Value::U32(1)]),
1001            Value::List(vec![Value::String("b".into()), Value::U32(2)]),
1002        ]);
1003        let m: HashMap<String, u32> = from_value(pairs.clone()).expect("list-of-pairs → map");
1004        assert_eq!(m.get("a"), Some(&1));
1005        assert_eq!(m.get("b"), Some(&2));
1006        // ...and the same value still reads as a `Vec<(K, V)>`.
1007        let v: Vec<(String, u32)> = from_value(pairs).expect("list-of-pairs → vec");
1008        assert_eq!(v.len(), 2);
1009        // A non-string-keyed map also round-trips (via Value::Map).
1010        let mut nk: HashMap<u32, String> = HashMap::new();
1011        nk.insert(7, "seven".into());
1012        round_trip(nk);
1013    }
1014
1015    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
1016    struct Greeting {
1017        name: String,
1018        times: u32,
1019        loud: bool,
1020    }
1021
1022    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
1023    struct Wrapper(u64);
1024
1025    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
1026    enum Shape {
1027        Unit,
1028        Newtype(i32),
1029        Tuple(i32, i32),
1030        Struct { w: u16, h: u16 },
1031    }
1032
1033    #[test]
1034    fn primitives() {
1035        round_trip(true);
1036        round_trip(-5i8);
1037        round_trip(40000u16);
1038        round_trip(u64::MAX);
1039        round_trip(i64::MIN);
1040        round_trip(3.5f32);
1041        round_trip(123.456_789_012_345f64);
1042        round_trip('λ');
1043        round_trip("hello".to_string());
1044    }
1045
1046    #[test]
1047    fn collections() {
1048        round_trip(vec![1i32, 2, 3]);
1049        round_trip(Some(7u8));
1050        round_trip(Option::<u8>::None);
1051        round_trip((1i32, "two".to_string(), false));
1052        round_trip(vec![Some(1u32), None, Some(3)]);
1053    }
1054
1055    #[test]
1056    fn structs_and_maps() {
1057        round_trip(Greeting {
1058            name: "ada".to_string(),
1059            times: 3,
1060            loud: true,
1061        });
1062        round_trip(Wrapper(99));
1063
1064        use std::collections::BTreeMap;
1065        let mut m = BTreeMap::new();
1066        m.insert("a".to_string(), 1i32);
1067        m.insert("b".to_string(), 2);
1068        round_trip(m);
1069
1070        let mut numkeys = BTreeMap::new();
1071        numkeys.insert(1u32, "one".to_string());
1072        numkeys.insert(2u32, "two".to_string());
1073        round_trip(numkeys);
1074    }
1075
1076    #[test]
1077    fn enums() {
1078        round_trip(Shape::Unit);
1079        round_trip(Shape::Newtype(-9));
1080        round_trip(Shape::Tuple(3, 4));
1081        round_trip(Shape::Struct { w: 10, h: 20 });
1082    }
1083
1084    #[test]
1085    fn nested() {
1086        #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
1087        struct Outer {
1088            shapes: Vec<Shape>,
1089            tag: Option<String>,
1090        }
1091        round_trip(Outer {
1092            shapes: vec![Shape::Unit, Shape::Tuple(1, 2), Shape::Newtype(5)],
1093            tag: Some("x".to_string()),
1094        });
1095    }
1096
1097    #[test]
1098    fn struct_shape_is_record() {
1099        let v = to_value(&Greeting {
1100            name: "z".into(),
1101            times: 1,
1102            loud: false,
1103        })
1104        .unwrap();
1105        match v {
1106            Value::Record(fields) => {
1107                assert_eq!(fields[0].0, "name");
1108                assert_eq!(fields[1].0, "times");
1109                assert_eq!(fields[2].0, "loud");
1110            }
1111            other => panic!("expected record, got {other:?}"),
1112        }
1113    }
1114}