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    serde::forward_to_deserialize_any! {
574        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
575        bytes byte_buf seq tuple tuple_struct map struct identifier
576        ignored_any
577    }
578}
579
580impl Value {
581    fn kind(&self) -> &'static str {
582        match self {
583            Value::Bool(_) => "bool",
584            Value::S8(_) | Value::S16(_) | Value::S32(_) | Value::S64(_) => "signed integer",
585            Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => "unsigned integer",
586            Value::F32(_) | Value::F64(_) => "float",
587            Value::Char(_) => "char",
588            Value::String(_) => "string",
589            Value::Bytes(_) => "bytes",
590            Value::Option(_) => "option",
591            Value::List(_) => "list",
592            Value::Record(_) => "record",
593            Value::Map(_) => "map",
594            Value::Variant { .. } => "variant",
595            Value::Unit => "unit",
596        }
597    }
598}
599
600struct SeqAccess {
601    iter: std::vec::IntoIter<Value>,
602}
603impl<'de> de::SeqAccess<'de> for SeqAccess {
604    type Error = ValueError;
605    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, ValueError>
606    where
607        T: de::DeserializeSeed<'de>,
608    {
609        match self.iter.next() {
610            Some(v) => seed.deserialize(v).map(Some),
611            None => Ok(None),
612        }
613    }
614    fn size_hint(&self) -> Option<usize> {
615        Some(self.iter.len())
616    }
617}
618
619struct RecordAccess {
620    iter: std::vec::IntoIter<(String, Value)>,
621    value: Option<Value>,
622}
623impl<'de> de::MapAccess<'de> for RecordAccess {
624    type Error = ValueError;
625    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, ValueError>
626    where
627        K: de::DeserializeSeed<'de>,
628    {
629        match self.iter.next() {
630            Some((k, v)) => {
631                self.value = Some(v);
632                seed.deserialize(Value::String(k)).map(Some)
633            }
634            None => Ok(None),
635        }
636    }
637    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, ValueError>
638    where
639        V: de::DeserializeSeed<'de>,
640    {
641        let v = self
642            .value
643            .take()
644            .ok_or_else(|| ValueError("next_value called before next_key".into()))?;
645        seed.deserialize(v)
646    }
647    fn size_hint(&self) -> Option<usize> {
648        Some(self.iter.len())
649    }
650}
651
652struct MapAccess {
653    iter: std::vec::IntoIter<(Value, Value)>,
654    value: Option<Value>,
655}
656impl<'de> de::MapAccess<'de> for MapAccess {
657    type Error = ValueError;
658    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, ValueError>
659    where
660        K: de::DeserializeSeed<'de>,
661    {
662        match self.iter.next() {
663            Some((k, v)) => {
664                self.value = Some(v);
665                seed.deserialize(k).map(Some)
666            }
667            None => Ok(None),
668        }
669    }
670    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, ValueError>
671    where
672        V: de::DeserializeSeed<'de>,
673    {
674        let v = self
675            .value
676            .take()
677            .ok_or_else(|| ValueError("next_value called before next_key".into()))?;
678        seed.deserialize(v)
679    }
680    fn size_hint(&self) -> Option<usize> {
681        Some(self.iter.len())
682    }
683}
684
685/// Presents a `Value::Variant` as a single-entry map for `deserialize_any`
686/// consumers (e.g. deserializing into `serde_json::Value`).
687struct SingletonMapAccess {
688    key: Option<String>,
689    value: Option<Value>,
690}
691impl<'de> de::MapAccess<'de> for SingletonMapAccess {
692    type Error = ValueError;
693    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, ValueError>
694    where
695        K: de::DeserializeSeed<'de>,
696    {
697        match self.key.take() {
698            Some(k) => seed.deserialize(Value::String(k)).map(Some),
699            None => Ok(None),
700        }
701    }
702    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, ValueError>
703    where
704        V: de::DeserializeSeed<'de>,
705    {
706        let v = self
707            .value
708            .take()
709            .ok_or_else(|| ValueError("variant value already consumed".into()))?;
710        seed.deserialize(v)
711    }
712}
713
714struct EnumAccess {
715    name: String,
716    value: Value,
717}
718impl<'de> de::EnumAccess<'de> for EnumAccess {
719    type Error = ValueError;
720    type Variant = VariantAccess;
721    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantAccess), ValueError>
722    where
723        V: de::DeserializeSeed<'de>,
724    {
725        let variant = seed.deserialize(Value::String(self.name))?;
726        Ok((variant, VariantAccess { value: self.value }))
727    }
728}
729
730struct VariantAccess {
731    value: Value,
732}
733impl<'de> de::VariantAccess<'de> for VariantAccess {
734    type Error = ValueError;
735    fn unit_variant(self) -> Result<(), ValueError> {
736        match self.value {
737            Value::Unit => Ok(()),
738            other => Err(ValueError(format!(
739                "expected unit variant, found {}",
740                other.kind()
741            ))),
742        }
743    }
744    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, ValueError>
745    where
746        T: de::DeserializeSeed<'de>,
747    {
748        seed.deserialize(self.value)
749    }
750    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, ValueError>
751    where
752        V: de::Visitor<'de>,
753    {
754        match self.value {
755            Value::List(items) => visitor.visit_seq(SeqAccess {
756                iter: items.into_iter(),
757            }),
758            other => Err(ValueError(format!(
759                "expected tuple variant, found {}",
760                other.kind()
761            ))),
762        }
763    }
764    fn struct_variant<V>(
765        self,
766        _fields: &'static [&'static str],
767        visitor: V,
768    ) -> Result<V::Value, ValueError>
769    where
770        V: de::Visitor<'de>,
771    {
772        match self.value {
773            Value::Record(fields) => visitor.visit_map(RecordAccess {
774                iter: fields.into_iter(),
775                value: None,
776            }),
777            other => Err(ValueError(format!(
778                "expected struct variant, found {}",
779                other.kind()
780            ))),
781        }
782    }
783}
784
785#[cfg(test)]
786mod tests {
787    use super::*;
788    use serde::{Deserialize, Serialize};
789
790    fn round_trip<T>(value: T)
791    where
792        T: Serialize + de::DeserializeOwned + PartialEq + fmt::Debug + Clone,
793    {
794        let v = to_value(&value).expect("to_value");
795        let back: T = from_value(v).expect("from_value");
796        assert_eq!(back, value);
797    }
798
799    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
800    struct Greeting {
801        name: String,
802        times: u32,
803        loud: bool,
804    }
805
806    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
807    struct Wrapper(u64);
808
809    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
810    enum Shape {
811        Unit,
812        Newtype(i32),
813        Tuple(i32, i32),
814        Struct { w: u16, h: u16 },
815    }
816
817    #[test]
818    fn primitives() {
819        round_trip(true);
820        round_trip(-5i8);
821        round_trip(40000u16);
822        round_trip(u64::MAX);
823        round_trip(i64::MIN);
824        round_trip(3.5f32);
825        round_trip(2.718281828f64);
826        round_trip('λ');
827        round_trip("hello".to_string());
828    }
829
830    #[test]
831    fn collections() {
832        round_trip(vec![1i32, 2, 3]);
833        round_trip(Some(7u8));
834        round_trip(Option::<u8>::None);
835        round_trip((1i32, "two".to_string(), false));
836        round_trip(vec![Some(1u32), None, Some(3)]);
837    }
838
839    #[test]
840    fn structs_and_maps() {
841        round_trip(Greeting {
842            name: "ada".to_string(),
843            times: 3,
844            loud: true,
845        });
846        round_trip(Wrapper(99));
847
848        use std::collections::BTreeMap;
849        let mut m = BTreeMap::new();
850        m.insert("a".to_string(), 1i32);
851        m.insert("b".to_string(), 2);
852        round_trip(m);
853
854        let mut numkeys = BTreeMap::new();
855        numkeys.insert(1u32, "one".to_string());
856        numkeys.insert(2u32, "two".to_string());
857        round_trip(numkeys);
858    }
859
860    #[test]
861    fn enums() {
862        round_trip(Shape::Unit);
863        round_trip(Shape::Newtype(-9));
864        round_trip(Shape::Tuple(3, 4));
865        round_trip(Shape::Struct { w: 10, h: 20 });
866    }
867
868    #[test]
869    fn nested() {
870        #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
871        struct Outer {
872            shapes: Vec<Shape>,
873            tag: Option<String>,
874        }
875        round_trip(Outer {
876            shapes: vec![Shape::Unit, Shape::Tuple(1, 2), Shape::Newtype(5)],
877            tag: Some("x".to_string()),
878        });
879    }
880
881    #[test]
882    fn struct_shape_is_record() {
883        let v = to_value(&Greeting {
884            name: "z".into(),
885            times: 1,
886            loud: false,
887        })
888        .unwrap();
889        match v {
890            Value::Record(fields) => {
891                assert_eq!(fields[0].0, "name");
892                assert_eq!(fields[1].0, "times");
893                assert_eq!(fields[2].0, "loud");
894            }
895            other => panic!("expected record, got {other:?}"),
896        }
897    }
898}
899
900// `Value` is itself serde-serializable so it can be embedded in other
901// structures and round-tripped through any format when needed.
902impl Serialize for Value {
903    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
904    where
905        S: ser::Serializer,
906    {
907        match self {
908            Value::Bool(v) => serializer.serialize_bool(*v),
909            Value::S8(v) => serializer.serialize_i8(*v),
910            Value::S16(v) => serializer.serialize_i16(*v),
911            Value::S32(v) => serializer.serialize_i32(*v),
912            Value::S64(v) => serializer.serialize_i64(*v),
913            Value::U8(v) => serializer.serialize_u8(*v),
914            Value::U16(v) => serializer.serialize_u16(*v),
915            Value::U32(v) => serializer.serialize_u32(*v),
916            Value::U64(v) => serializer.serialize_u64(*v),
917            Value::F32(v) => serializer.serialize_f32(*v),
918            Value::F64(v) => serializer.serialize_f64(*v),
919            Value::Char(v) => serializer.serialize_char(*v),
920            Value::String(v) => serializer.serialize_str(v),
921            Value::Bytes(v) => serializer.serialize_bytes(v),
922            Value::Unit => serializer.serialize_unit(),
923            Value::Option(None) => serializer.serialize_none(),
924            Value::Option(Some(v)) => serializer.serialize_some(v),
925            Value::List(items) => {
926                use ser::SerializeSeq;
927                let mut seq = serializer.serialize_seq(Some(items.len()))?;
928                for item in items {
929                    seq.serialize_element(item)?;
930                }
931                seq.end()
932            }
933            Value::Record(fields) => {
934                use ser::SerializeMap;
935                let mut map = serializer.serialize_map(Some(fields.len()))?;
936                for (k, v) in fields {
937                    map.serialize_entry(k, v)?;
938                }
939                map.end()
940            }
941            Value::Map(entries) => {
942                use ser::SerializeMap;
943                let mut map = serializer.serialize_map(Some(entries.len()))?;
944                for (k, v) in entries {
945                    map.serialize_entry(k, v)?;
946                }
947                map.end()
948            }
949            Value::Variant { name, value } => {
950                use ser::SerializeMap;
951                let mut map = serializer.serialize_map(Some(1))?;
952                map.serialize_entry(name, value)?;
953                map.end()
954            }
955        }
956    }
957}
958
959impl<'de> Deserialize<'de> for Value {
960    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
961    where
962        D: de::Deserializer<'de>,
963    {
964        struct ValueVisitor;
965        impl<'de> de::Visitor<'de> for ValueVisitor {
966            type Value = Value;
967            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
968                f.write_str("any fidius value")
969            }
970            fn visit_bool<E>(self, v: bool) -> Result<Value, E> {
971                Ok(Value::Bool(v))
972            }
973            fn visit_i64<E>(self, v: i64) -> Result<Value, E> {
974                Ok(Value::S64(v))
975            }
976            fn visit_i128<E>(self, v: i128) -> Result<Value, E>
977            where
978                E: de::Error,
979            {
980                i64::try_from(v)
981                    .map(Value::S64)
982                    .map_err(|_| E::custom("i128 out of range"))
983            }
984            fn visit_u64<E>(self, v: u64) -> Result<Value, E> {
985                Ok(Value::U64(v))
986            }
987            fn visit_u128<E>(self, v: u128) -> Result<Value, E>
988            where
989                E: de::Error,
990            {
991                u64::try_from(v)
992                    .map(Value::U64)
993                    .map_err(|_| E::custom("u128 out of range"))
994            }
995            fn visit_f64<E>(self, v: f64) -> Result<Value, E> {
996                Ok(Value::F64(v))
997            }
998            fn visit_char<E>(self, v: char) -> Result<Value, E> {
999                Ok(Value::Char(v))
1000            }
1001            fn visit_str<E>(self, v: &str) -> Result<Value, E> {
1002                Ok(Value::String(v.to_string()))
1003            }
1004            fn visit_string<E>(self, v: String) -> Result<Value, E> {
1005                Ok(Value::String(v))
1006            }
1007            fn visit_bytes<E>(self, v: &[u8]) -> Result<Value, E> {
1008                Ok(Value::Bytes(v.to_vec()))
1009            }
1010            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Value, E> {
1011                Ok(Value::Bytes(v))
1012            }
1013            fn visit_unit<E>(self) -> Result<Value, E> {
1014                Ok(Value::Unit)
1015            }
1016            fn visit_none<E>(self) -> Result<Value, E> {
1017                Ok(Value::Option(None))
1018            }
1019            fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
1020            where
1021                D: de::Deserializer<'de>,
1022            {
1023                Ok(Value::Option(Some(Box::new(Value::deserialize(
1024                    deserializer,
1025                )?))))
1026            }
1027            fn visit_seq<A>(self, mut seq: A) -> Result<Value, A::Error>
1028            where
1029                A: de::SeqAccess<'de>,
1030            {
1031                let mut items = Vec::new();
1032                while let Some(v) = seq.next_element()? {
1033                    items.push(v);
1034                }
1035                Ok(Value::List(items))
1036            }
1037            fn visit_map<A>(self, mut map: A) -> Result<Value, A::Error>
1038            where
1039                A: de::MapAccess<'de>,
1040            {
1041                let mut fields = Vec::new();
1042                while let Some((k, v)) = map.next_entry::<String, Value>()? {
1043                    fields.push((k, v));
1044                }
1045                Ok(Value::Record(fields))
1046            }
1047        }
1048        deserializer.deserialize_any(ValueVisitor)
1049    }
1050}