Skip to main content

packr_abi/
value.rs

1//! Runtime values
2
3use alloc::boxed::Box;
4use alloc::collections::{BTreeMap, BTreeSet};
5use alloc::string::String;
6use alloc::vec::Vec;
7
8/// Runtime type representation for CGRF v2
9#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum ValueType {
12    Bool,
13    U8,
14    U16,
15    U32,
16    U64,
17    S8,
18    S16,
19    S32,
20    S64,
21    F32,
22    F64,
23    Char,
24    String,
25    List(Box<ValueType>),
26    Option(Box<ValueType>),
27    Result {
28        ok: Box<ValueType>,
29        err: Box<ValueType>,
30    },
31    Record(String),  // type name
32    Variant(String), // type name
33    Tuple(Vec<ValueType>),
34    Flags,
35}
36
37impl core::fmt::Display for ValueType {
38    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
39        match self {
40            ValueType::Bool => write!(f, "bool"),
41            ValueType::U8 => write!(f, "u8"),
42            ValueType::U16 => write!(f, "u16"),
43            ValueType::U32 => write!(f, "u32"),
44            ValueType::U64 => write!(f, "u64"),
45            ValueType::S8 => write!(f, "s8"),
46            ValueType::S16 => write!(f, "s16"),
47            ValueType::S32 => write!(f, "s32"),
48            ValueType::S64 => write!(f, "s64"),
49            ValueType::F32 => write!(f, "f32"),
50            ValueType::F64 => write!(f, "f64"),
51            ValueType::Char => write!(f, "char"),
52            ValueType::String => write!(f, "string"),
53            ValueType::List(inner) => write!(f, "list<{}>", inner),
54            ValueType::Option(inner) => write!(f, "option<{}>", inner),
55            ValueType::Result { ok, err } => write!(f, "result<{}, {}>", ok, err),
56            ValueType::Record(name) => write!(f, "{}", name),
57            ValueType::Variant(name) => write!(f, "{}", name),
58            ValueType::Tuple(types) => {
59                write!(f, "tuple<")?;
60                for (i, t) in types.iter().enumerate() {
61                    if i > 0 {
62                        write!(f, ", ")?;
63                    }
64                    write!(f, "{}", t)?;
65                }
66                write!(f, ">")
67            }
68            ValueType::Flags => write!(f, "flags"),
69        }
70    }
71}
72
73/// A runtime value that can be passed across package boundaries
74#[derive(Debug, Clone, PartialEq)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76pub enum Value {
77    // Primitives
78    Bool(bool),
79    U8(u8),
80    U16(u16),
81    U32(u32),
82    U64(u64),
83    S8(i8),
84    S16(i16),
85    S32(i32),
86    S64(i64),
87    F32(f32),
88    F64(f64),
89    Char(char),
90    String(String),
91
92    // Compound types WITH type info
93    List {
94        elem_type: ValueType,
95        items: Vec<Value>,
96    },
97    Option {
98        inner_type: ValueType,
99        value: Option<Box<Value>>,
100    },
101    Result {
102        ok_type: ValueType,
103        err_type: ValueType,
104        value: core::result::Result<Box<Value>, Box<Value>>,
105    },
106    Record {
107        type_name: String,
108        fields: Vec<(String, Value)>,
109    },
110    Variant {
111        type_name: String,
112        case_name: String,
113        tag: usize,
114        payload: Vec<Value>,
115    },
116
117    // Keep Tuple as-is (no type info needed - positional)
118    Tuple(Vec<Value>),
119    Flags(u64),
120}
121
122impl Value {
123    /// Helper to create a symbol (variant tag 0 with string payload)
124    pub fn sym(s: impl Into<String>) -> Self {
125        Value::Variant {
126            type_name: String::from("expr"),
127            case_name: String::from("sym"),
128            tag: 0,
129            payload: alloc::vec![Value::String(s.into())],
130        }
131    }
132
133    /// Helper to create a number (variant tag 1 with s64 payload)
134    pub fn num(n: i64) -> Self {
135        Value::Variant {
136            type_name: String::from("expr"),
137            case_name: String::from("num"),
138            tag: 1,
139            payload: alloc::vec![Value::S64(n)],
140        }
141    }
142
143    /// Helper to create a list (variant tag 4 with list payload)
144    pub fn lst(items: Vec<Value>) -> Self {
145        Value::Variant {
146            type_name: String::from("expr"),
147            case_name: String::from("lst"),
148            tag: 4,
149            payload: alloc::vec![Value::List {
150                elem_type: ValueType::Variant(String::from("expr")),
151                items,
152            }],
153        }
154    }
155
156    /// Infer the ValueType from this Value
157    pub fn infer_type(&self) -> ValueType {
158        match self {
159            Value::Bool(_) => ValueType::Bool,
160            Value::U8(_) => ValueType::U8,
161            Value::U16(_) => ValueType::U16,
162            Value::U32(_) => ValueType::U32,
163            Value::U64(_) => ValueType::U64,
164            Value::S8(_) => ValueType::S8,
165            Value::S16(_) => ValueType::S16,
166            Value::S32(_) => ValueType::S32,
167            Value::S64(_) => ValueType::S64,
168            Value::F32(_) => ValueType::F32,
169            Value::F64(_) => ValueType::F64,
170            Value::Char(_) => ValueType::Char,
171            Value::String(_) => ValueType::String,
172            Value::List { elem_type, .. } => ValueType::List(Box::new(elem_type.clone())),
173            Value::Option { inner_type, .. } => ValueType::Option(Box::new(inner_type.clone())),
174            Value::Result {
175                ok_type, err_type, ..
176            } => ValueType::Result {
177                ok: Box::new(ok_type.clone()),
178                err: Box::new(err_type.clone()),
179            },
180            Value::Record { type_name, .. } => ValueType::Record(type_name.clone()),
181            Value::Variant { type_name, .. } => ValueType::Variant(type_name.clone()),
182            Value::Tuple(items) => ValueType::Tuple(items.iter().map(|v| v.infer_type()).collect()),
183            Value::Flags(_) => ValueType::Flags,
184        }
185    }
186}
187
188impl core::fmt::Display for Value {
189    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
190        match self {
191            Value::Bool(v) => write!(f, "{}", v),
192            Value::U8(v) => write!(f, "{}u8", v),
193            Value::U16(v) => write!(f, "{}u16", v),
194            Value::U32(v) => write!(f, "{}u32", v),
195            Value::U64(v) => write!(f, "{}u64", v),
196            Value::S8(v) => write!(f, "{}s8", v),
197            Value::S16(v) => write!(f, "{}s16", v),
198            Value::S32(v) => write!(f, "{}s32", v),
199            Value::S64(v) => write!(f, "{}s64", v),
200            Value::F32(v) => {
201                // Ensure float always has a decimal point for unambiguous parsing
202                let s = alloc::format!("{}", v);
203                if v.is_finite() && !s.contains('.') {
204                    write!(f, "{}.0f32", s)
205                } else {
206                    write!(f, "{}f32", s)
207                }
208            }
209            Value::F64(v) => {
210                let s = alloc::format!("{}", v);
211                if v.is_finite() && !s.contains('.') {
212                    write!(f, "{}.0f64", s)
213                } else {
214                    write!(f, "{}f64", s)
215                }
216            }
217            Value::Char(v) => match v {
218                '\n' => write!(f, "'\\n'"),
219                '\r' => write!(f, "'\\r'"),
220                '\t' => write!(f, "'\\t'"),
221                '\\' => write!(f, "'\\\\'"),
222                '\'' => write!(f, "'\\''"),
223                c => write!(f, "'{}'", c),
224            },
225            Value::String(v) => {
226                write!(f, "\"")?;
227                for c in v.chars() {
228                    match c {
229                        '"' => write!(f, "\\\"")?,
230                        '\\' => write!(f, "\\\\")?,
231                        '\n' => write!(f, "\\n")?,
232                        '\r' => write!(f, "\\r")?,
233                        '\t' => write!(f, "\\t")?,
234                        c => write!(f, "{}", c)?,
235                    }
236                }
237                write!(f, "\"")
238            }
239            Value::Tuple(items) => {
240                write!(f, "(")?;
241                for (i, item) in items.iter().enumerate() {
242                    if i > 0 {
243                        write!(f, ", ")?;
244                    }
245                    write!(f, "{}", item)?;
246                }
247                write!(f, ")")
248            }
249            Value::List { elem_type, items } => {
250                if items.is_empty() {
251                    // Empty list: annotate elem_type since we can't infer it
252                    write!(f, "[]<{}>", elem_type)
253                } else {
254                    write!(f, "[")?;
255                    for (i, item) in items.iter().enumerate() {
256                        if i > 0 {
257                            write!(f, ", ")?;
258                        }
259                        write!(f, "{}", item)?;
260                    }
261                    write!(f, "]")
262                }
263            }
264            Value::Option { inner_type, value } => match value {
265                // Always annotate inner_type — the stored type may not match the value's type
266                Some(v) => write!(f, "some<{}>({})", inner_type, v),
267                None => write!(f, "none<{}>", inner_type),
268            },
269            Value::Result {
270                ok_type,
271                err_type,
272                value,
273            } => match value {
274                // Always annotate both types — the stored types may not match the value's type
275                Ok(v) => write!(f, "ok<{}, {}>({})", ok_type, err_type, v),
276                Err(v) => write!(f, "err<{}, {}>({})", ok_type, err_type, v),
277            },
278            Value::Record { type_name, fields } => {
279                if type_name.is_empty() {
280                    write!(f, "{{")?;
281                } else {
282                    write!(f, "{}{{", type_name)?;
283                }
284                for (i, (name, value)) in fields.iter().enumerate() {
285                    if i > 0 {
286                        write!(f, ", ")?;
287                    }
288                    write!(f, "{}: {}", name, value)?;
289                }
290                write!(f, "}}")
291            }
292            Value::Variant {
293                type_name,
294                case_name,
295                payload,
296                ..
297            } => {
298                // Always emit :: to distinguish from keywords (some/none/ok/err)
299                write!(f, "{}::{}", type_name, case_name)?;
300                if !payload.is_empty() {
301                    write!(f, "(")?;
302                    for (i, v) in payload.iter().enumerate() {
303                        if i > 0 {
304                            write!(f, ", ")?;
305                        }
306                        write!(f, "{}", v)?;
307                    }
308                    write!(f, ")")?;
309                }
310                Ok(())
311            }
312            Value::Flags(v) => write!(f, "flags(0x{:x})", v),
313        }
314    }
315}
316
317// ============================================================================
318// From implementations for primitives
319// ============================================================================
320
321impl From<bool> for Value {
322    fn from(v: bool) -> Self {
323        Value::Bool(v)
324    }
325}
326
327impl From<u8> for Value {
328    fn from(v: u8) -> Self {
329        Value::U8(v)
330    }
331}
332
333impl From<u16> for Value {
334    fn from(v: u16) -> Self {
335        Value::U16(v)
336    }
337}
338
339impl From<u32> for Value {
340    fn from(v: u32) -> Self {
341        Value::U32(v)
342    }
343}
344
345impl From<u64> for Value {
346    fn from(v: u64) -> Self {
347        Value::U64(v)
348    }
349}
350
351impl From<i8> for Value {
352    fn from(v: i8) -> Self {
353        Value::S8(v)
354    }
355}
356
357impl From<i16> for Value {
358    fn from(v: i16) -> Self {
359        Value::S16(v)
360    }
361}
362
363impl From<i32> for Value {
364    fn from(v: i32) -> Self {
365        Value::S32(v)
366    }
367}
368
369impl From<i64> for Value {
370    fn from(v: i64) -> Self {
371        Value::S64(v)
372    }
373}
374
375impl From<f32> for Value {
376    fn from(v: f32) -> Self {
377        Value::F32(v)
378    }
379}
380
381impl From<f64> for Value {
382    fn from(v: f64) -> Self {
383        Value::F64(v)
384    }
385}
386
387impl From<char> for Value {
388    fn from(v: char) -> Self {
389        Value::Char(v)
390    }
391}
392
393impl From<String> for Value {
394    fn from(v: String) -> Self {
395        Value::String(v)
396    }
397}
398
399impl From<&str> for Value {
400    fn from(v: &str) -> Self {
401        Value::String(String::from(v))
402    }
403}
404
405// ============================================================================
406// KnownValueType — compile-time ValueType for a Rust type.
407// ============================================================================
408//
409// The runtime `infer_type` only works on a concrete value; an empty
410// `Vec<T>` or `None: Option<T>` carries no information. To encode an
411// empty `Vec<Binding>` correctly (as `list<binding>`, not the default
412// `list<s32>`), we need T's ValueType at the type level. Types implement
413// `KnownValueType` to declare it — primitives statically, records via
414// the `#[derive(GraphValue)]` macro.
415
416/// Compile-time `ValueType` for a Rust type. Used by `From<Vec<T>>` and
417/// `From<Option<T>>` so that empty containers still encode with the
418/// correct element/inner type.
419pub trait KnownValueType {
420    fn known_value_type() -> ValueType;
421}
422
423macro_rules! known_primitive {
424    ($t:ty, $vt:expr) => {
425        impl KnownValueType for $t {
426            fn known_value_type() -> ValueType {
427                $vt
428            }
429        }
430    };
431}
432known_primitive!(bool, ValueType::Bool);
433known_primitive!(u8, ValueType::U8);
434known_primitive!(u16, ValueType::U16);
435known_primitive!(u32, ValueType::U32);
436known_primitive!(u64, ValueType::U64);
437known_primitive!(i8, ValueType::S8);
438known_primitive!(i16, ValueType::S16);
439known_primitive!(i32, ValueType::S32);
440known_primitive!(i64, ValueType::S64);
441known_primitive!(f32, ValueType::F32);
442known_primitive!(f64, ValueType::F64);
443known_primitive!(char, ValueType::Char);
444known_primitive!(String, ValueType::String);
445
446impl<T: KnownValueType> KnownValueType for Vec<T> {
447    fn known_value_type() -> ValueType {
448        ValueType::List(Box::new(T::known_value_type()))
449    }
450}
451
452impl<T: KnownValueType> KnownValueType for Option<T> {
453    fn known_value_type() -> ValueType {
454        ValueType::Option(Box::new(T::known_value_type()))
455    }
456}
457
458impl<T: KnownValueType, E: KnownValueType> KnownValueType for core::result::Result<T, E> {
459    fn known_value_type() -> ValueType {
460        ValueType::Result {
461            ok: Box::new(T::known_value_type()),
462            err: Box::new(E::known_value_type()),
463        }
464    }
465}
466
467impl<T: KnownValueType> KnownValueType for Box<T> {
468    fn known_value_type() -> ValueType {
469        T::known_value_type()
470    }
471}
472
473impl KnownValueType for () {
474    fn known_value_type() -> ValueType {
475        ValueType::Tuple(Vec::new())
476    }
477}
478
479/// `Value` is dynamic — its actual ValueType is only known at runtime
480/// (`Value::infer_type`). The compile-time fallback is `String`, matching
481/// the previous `PackType for Value` behavior. Prefer concrete types when
482/// you need accurate static typing.
483impl KnownValueType for Value {
484    fn known_value_type() -> ValueType {
485        ValueType::String
486    }
487}
488
489impl<A: KnownValueType> KnownValueType for (A,) {
490    fn known_value_type() -> ValueType {
491        ValueType::Tuple(alloc::vec![A::known_value_type()])
492    }
493}
494
495impl<A: KnownValueType, B: KnownValueType> KnownValueType for (A, B) {
496    fn known_value_type() -> ValueType {
497        ValueType::Tuple(alloc::vec![A::known_value_type(), B::known_value_type()])
498    }
499}
500
501impl<A: KnownValueType, B: KnownValueType, C: KnownValueType> KnownValueType for (A, B, C) {
502    fn known_value_type() -> ValueType {
503        ValueType::Tuple(alloc::vec![
504            A::known_value_type(),
505            B::known_value_type(),
506            C::known_value_type()
507        ])
508    }
509}
510
511impl<A: KnownValueType, B: KnownValueType, C: KnownValueType, D: KnownValueType> KnownValueType
512    for (A, B, C, D)
513{
514    fn known_value_type() -> ValueType {
515        ValueType::Tuple(alloc::vec![
516            A::known_value_type(),
517            B::known_value_type(),
518            C::known_value_type(),
519            D::known_value_type()
520        ])
521    }
522}
523
524// ============================================================================
525// From implementations for collections — use KnownValueType for the
526// element/inner type so empty values still carry correct type info.
527// ============================================================================
528
529impl<T: Into<Value> + KnownValueType> From<Vec<T>> for Value {
530    fn from(v: Vec<T>) -> Self {
531        let items: Vec<Value> = v.into_iter().map(Into::into).collect();
532        Value::List {
533            elem_type: T::known_value_type(),
534            items,
535        }
536    }
537}
538
539impl<T: Into<Value> + KnownValueType, const N: usize> From<[T; N]> for Value {
540    fn from(v: [T; N]) -> Self {
541        let items: Vec<Value> = v.into_iter().map(Into::into).collect();
542        Value::List {
543            elem_type: T::known_value_type(),
544            items,
545        }
546    }
547}
548
549impl<T: TryFrom<Value, Error = ConversionError>, const N: usize> TryFrom<Value> for [T; N] {
550    type Error = ConversionError;
551    fn try_from(v: Value) -> Result<Self, Self::Error> {
552        match v {
553            Value::List { items, .. } => {
554                if items.len() != N {
555                    return Err(ConversionError::WrongFieldCount {
556                        expected: N,
557                        got: items.len(),
558                    });
559                }
560                let vec: Vec<T> = items
561                    .into_iter()
562                    .enumerate()
563                    .map(|(i, item)| {
564                        T::try_from(item).map_err(|e| ConversionError::IndexError(i, Box::new(e)))
565                    })
566                    .collect::<Result<Vec<T>, _>>()?;
567                vec.try_into().map_err(|_| {
568                    ConversionError::ExpectedList(String::from("array conversion failed"))
569                })
570            }
571            other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
572        }
573    }
574}
575
576impl<T: Into<Value> + KnownValueType> From<Option<T>> for Value {
577    fn from(v: Option<T>) -> Self {
578        Value::Option {
579            inner_type: T::known_value_type(),
580            value: v.map(|x| Box::new(x.into())),
581        }
582    }
583}
584
585impl<T: Into<Value>> From<Box<T>> for Value {
586    fn from(v: Box<T>) -> Self {
587        (*v).into()
588    }
589}
590
591// ============================================================================
592// TryFrom implementations for primitives
593// ============================================================================
594
595use crate::ConversionError;
596
597impl TryFrom<Value> for bool {
598    type Error = ConversionError;
599    fn try_from(v: Value) -> Result<Self, Self::Error> {
600        match v {
601            Value::Bool(x) => Ok(x),
602            other => Err(ConversionError::TypeMismatch {
603                expected: String::from("bool"),
604                got: format!("{:?}", other),
605            }),
606        }
607    }
608}
609
610impl TryFrom<Value> for u8 {
611    type Error = ConversionError;
612    fn try_from(v: Value) -> Result<Self, Self::Error> {
613        match v {
614            Value::U8(x) => Ok(x),
615            other => Err(ConversionError::TypeMismatch {
616                expected: String::from("u8"),
617                got: format!("{:?}", other),
618            }),
619        }
620    }
621}
622
623impl TryFrom<Value> for u16 {
624    type Error = ConversionError;
625    fn try_from(v: Value) -> Result<Self, Self::Error> {
626        match v {
627            Value::U16(x) => Ok(x),
628            other => Err(ConversionError::TypeMismatch {
629                expected: String::from("u16"),
630                got: format!("{:?}", other),
631            }),
632        }
633    }
634}
635
636impl TryFrom<Value> for u32 {
637    type Error = ConversionError;
638    fn try_from(v: Value) -> Result<Self, Self::Error> {
639        match v {
640            Value::U32(x) => Ok(x),
641            other => Err(ConversionError::TypeMismatch {
642                expected: String::from("u32"),
643                got: format!("{:?}", other),
644            }),
645        }
646    }
647}
648
649impl TryFrom<Value> for u64 {
650    type Error = ConversionError;
651    fn try_from(v: Value) -> Result<Self, Self::Error> {
652        match v {
653            Value::U64(x) => Ok(x),
654            other => Err(ConversionError::TypeMismatch {
655                expected: String::from("u64"),
656                got: format!("{:?}", other),
657            }),
658        }
659    }
660}
661
662impl TryFrom<Value> for i8 {
663    type Error = ConversionError;
664    fn try_from(v: Value) -> Result<Self, Self::Error> {
665        match v {
666            Value::S8(x) => Ok(x),
667            other => Err(ConversionError::TypeMismatch {
668                expected: String::from("i8"),
669                got: format!("{:?}", other),
670            }),
671        }
672    }
673}
674
675impl TryFrom<Value> for i16 {
676    type Error = ConversionError;
677    fn try_from(v: Value) -> Result<Self, Self::Error> {
678        match v {
679            Value::S16(x) => Ok(x),
680            other => Err(ConversionError::TypeMismatch {
681                expected: String::from("i16"),
682                got: format!("{:?}", other),
683            }),
684        }
685    }
686}
687
688impl TryFrom<Value> for i32 {
689    type Error = ConversionError;
690    fn try_from(v: Value) -> Result<Self, Self::Error> {
691        match v {
692            Value::S32(x) => Ok(x),
693            other => Err(ConversionError::TypeMismatch {
694                expected: String::from("i32"),
695                got: format!("{:?}", other),
696            }),
697        }
698    }
699}
700
701impl TryFrom<Value> for i64 {
702    type Error = ConversionError;
703    fn try_from(v: Value) -> Result<Self, Self::Error> {
704        match v {
705            Value::S64(x) => Ok(x),
706            other => Err(ConversionError::TypeMismatch {
707                expected: String::from("i64"),
708                got: format!("{:?}", other),
709            }),
710        }
711    }
712}
713
714impl TryFrom<Value> for f32 {
715    type Error = ConversionError;
716    fn try_from(v: Value) -> Result<Self, Self::Error> {
717        match v {
718            Value::F32(x) => Ok(x),
719            other => Err(ConversionError::TypeMismatch {
720                expected: String::from("f32"),
721                got: format!("{:?}", other),
722            }),
723        }
724    }
725}
726
727impl TryFrom<Value> for f64 {
728    type Error = ConversionError;
729    fn try_from(v: Value) -> Result<Self, Self::Error> {
730        match v {
731            Value::F64(x) => Ok(x),
732            other => Err(ConversionError::TypeMismatch {
733                expected: String::from("f64"),
734                got: format!("{:?}", other),
735            }),
736        }
737    }
738}
739
740impl TryFrom<Value> for char {
741    type Error = ConversionError;
742    fn try_from(v: Value) -> Result<Self, Self::Error> {
743        match v {
744            Value::Char(x) => Ok(x),
745            other => Err(ConversionError::TypeMismatch {
746                expected: String::from("char"),
747                got: format!("{:?}", other),
748            }),
749        }
750    }
751}
752
753impl TryFrom<Value> for String {
754    type Error = ConversionError;
755    fn try_from(v: Value) -> Result<Self, Self::Error> {
756        match v {
757            Value::String(x) => Ok(x),
758            other => Err(ConversionError::TypeMismatch {
759                expected: String::from("String"),
760                got: format!("{:?}", other),
761            }),
762        }
763    }
764}
765
766impl<T: TryFrom<Value, Error = ConversionError>> TryFrom<Value> for Vec<T> {
767    type Error = ConversionError;
768    fn try_from(v: Value) -> Result<Self, Self::Error> {
769        match v {
770            Value::List { items, .. } => items
771                .into_iter()
772                .enumerate()
773                .map(|(i, item)| {
774                    T::try_from(item).map_err(|e| ConversionError::IndexError(i, Box::new(e)))
775                })
776                .collect(),
777            other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
778        }
779    }
780}
781
782impl<T: Into<Value> + KnownValueType + Ord> From<BTreeSet<T>> for Value {
783    fn from(v: BTreeSet<T>) -> Self {
784        let items: Vec<Value> = v.into_iter().map(Into::into).collect();
785        Value::List {
786            elem_type: T::known_value_type(),
787            items,
788        }
789    }
790}
791
792impl<T: TryFrom<Value, Error = ConversionError> + Ord> TryFrom<Value> for BTreeSet<T> {
793    type Error = ConversionError;
794    fn try_from(v: Value) -> Result<Self, Self::Error> {
795        match v {
796            Value::List { items, .. } => items
797                .into_iter()
798                .enumerate()
799                .map(|(i, item)| {
800                    T::try_from(item).map_err(|e| ConversionError::IndexError(i, Box::new(e)))
801                })
802                .collect(),
803            other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
804        }
805    }
806}
807
808impl<K: Into<Value> + KnownValueType + Ord, V: Into<Value> + KnownValueType> From<BTreeMap<K, V>>
809    for Value
810{
811    fn from(v: BTreeMap<K, V>) -> Self {
812        let items: Vec<Value> = v
813            .into_iter()
814            .map(|(k, v)| Value::Tuple(Vec::from([k.into(), v.into()])))
815            .collect();
816        Value::List {
817            elem_type: ValueType::Tuple(alloc::vec![K::known_value_type(), V::known_value_type()]),
818            items,
819        }
820    }
821}
822
823impl<
824        K: TryFrom<Value, Error = ConversionError> + Ord,
825        V: TryFrom<Value, Error = ConversionError>,
826    > TryFrom<Value> for BTreeMap<K, V>
827{
828    type Error = ConversionError;
829    fn try_from(v: Value) -> Result<Self, Self::Error> {
830        match v {
831            Value::List { items, .. } => items
832                .into_iter()
833                .enumerate()
834                .map(|(i, item)| match item {
835                    Value::Tuple(mut fields) if fields.len() == 2 => {
836                        let v_val = fields.pop().unwrap();
837                        let k_val = fields.pop().unwrap();
838                        let k = K::try_from(k_val)
839                            .map_err(|e| ConversionError::IndexError(i, Box::new(e)))?;
840                        let v = V::try_from(v_val)
841                            .map_err(|e| ConversionError::IndexError(i, Box::new(e)))?;
842                        Ok((k, v))
843                    }
844                    other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
845                })
846                .collect(),
847            other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
848        }
849    }
850}
851
852// ============================================================================
853// FromValue trait - avoids coherence issues with TryFrom for Option<T>
854// ============================================================================
855
856/// Trait for converting from a Value.
857///
858/// This trait exists to avoid coherence issues with Rust's blanket
859/// `impl<T, U> TryFrom<U> for T where U: Into<T>` when implementing
860/// conversions for generic types like `Option<T>`.
861pub trait FromValue: Sized {
862    fn from_value(v: Value) -> Result<Self, ConversionError>;
863}
864
865/// Blanket implementation for all types that implement TryFrom<Value>
866impl<T: TryFrom<Value, Error = ConversionError>> FromValue for T {
867    fn from_value(v: Value) -> Result<Self, ConversionError> {
868        T::try_from(v)
869    }
870}
871
872/// FromValue implementation for Value itself (identity conversion)
873impl FromValue for Value {
874    fn from_value(v: Value) -> Result<Self, ConversionError> {
875        Ok(v)
876    }
877}
878
879/// FromValue implementation for Option<T> - uses FromValue bound to avoid coherence issues
880impl<T: FromValue> FromValue for Option<T> {
881    fn from_value(v: Value) -> Result<Self, ConversionError> {
882        match v {
883            Value::Option { value: None, .. } => Ok(None),
884            Value::Option {
885                value: Some(inner), ..
886            } => {
887                let value = T::from_value(*inner)?;
888                Ok(Some(value))
889            }
890            other => Err(ConversionError::ExpectedOption(format!("{:?}", other))),
891        }
892    }
893}
894
895/// FromValue implementation for Result<T, E> - uses FromValue bounds to support nested Option types
896impl<T: FromValue, E: FromValue> FromValue for core::result::Result<T, E> {
897    fn from_value(v: Value) -> Result<Self, ConversionError> {
898        match v {
899            Value::Result {
900                value: Ok(inner), ..
901            } => {
902                let value = T::from_value(*inner)
903                    .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
904                Ok(Ok(value))
905            }
906            Value::Result {
907                value: Err(inner), ..
908            } => {
909                let value = E::from_value(*inner)
910                    .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
911                Ok(Err(value))
912            }
913            // Also support legacy variant encoding for backwards compatibility
914            Value::Variant {
915                tag: 0, payload, ..
916            } if !payload.is_empty() => {
917                let value = T::from_value(payload.into_iter().next().unwrap())
918                    .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
919                Ok(Ok(value))
920            }
921            Value::Variant {
922                tag: 1, payload, ..
923            } if !payload.is_empty() => {
924                let value = E::from_value(payload.into_iter().next().unwrap())
925                    .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
926                Ok(Err(value))
927            }
928            Value::Variant { tag, .. } => Err(ConversionError::UnknownTag { tag, max: 1 }),
929            other => Err(ConversionError::ExpectedVariant(format!("{:?}", other))),
930        }
931    }
932}
933
934// ============================================================================
935// Tuple conversions (for common sizes)
936// ============================================================================
937
938// Empty tuple / unit
939impl From<()> for Value {
940    fn from(_: ()) -> Self {
941        Value::Tuple(Vec::new())
942    }
943}
944
945impl TryFrom<Value> for () {
946    type Error = ConversionError;
947    fn try_from(v: Value) -> Result<Self, Self::Error> {
948        match v {
949            Value::Tuple(items) if items.is_empty() => Ok(()),
950            other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
951        }
952    }
953}
954
955// 1-tuple
956impl<A: Into<Value>> From<(A,)> for Value {
957    fn from((a,): (A,)) -> Self {
958        Value::Tuple(alloc::vec![a.into()])
959    }
960}
961
962impl<A: TryFrom<Value, Error = ConversionError>> TryFrom<Value> for (A,) {
963    type Error = ConversionError;
964    fn try_from(v: Value) -> Result<Self, Self::Error> {
965        match v {
966            Value::Tuple(mut items) if items.len() == 1 => {
967                let a = A::try_from(items.remove(0))
968                    .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
969                Ok((a,))
970            }
971            other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
972        }
973    }
974}
975
976// 2-tuple
977impl<A: Into<Value>, B: Into<Value>> From<(A, B)> for Value {
978    fn from((a, b): (A, B)) -> Self {
979        Value::Tuple(alloc::vec![a.into(), b.into()])
980    }
981}
982
983impl<A: TryFrom<Value, Error = ConversionError>, B: TryFrom<Value, Error = ConversionError>>
984    TryFrom<Value> for (A, B)
985{
986    type Error = ConversionError;
987    fn try_from(v: Value) -> Result<Self, Self::Error> {
988        match v {
989            Value::Tuple(mut items) if items.len() == 2 => {
990                let b = B::try_from(items.remove(1))
991                    .map_err(|e| ConversionError::IndexError(1, Box::new(e)))?;
992                let a = A::try_from(items.remove(0))
993                    .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
994                Ok((a, b))
995            }
996            other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
997        }
998    }
999}
1000
1001// 3-tuple
1002impl<A: Into<Value>, B: Into<Value>, C: Into<Value>> From<(A, B, C)> for Value {
1003    fn from((a, b, c): (A, B, C)) -> Self {
1004        Value::Tuple(alloc::vec![a.into(), b.into(), c.into()])
1005    }
1006}
1007
1008impl<
1009        A: TryFrom<Value, Error = ConversionError>,
1010        B: TryFrom<Value, Error = ConversionError>,
1011        C: TryFrom<Value, Error = ConversionError>,
1012    > TryFrom<Value> for (A, B, C)
1013{
1014    type Error = ConversionError;
1015    fn try_from(v: Value) -> Result<Self, Self::Error> {
1016        match v {
1017            Value::Tuple(mut items) if items.len() == 3 => {
1018                let c = C::try_from(items.remove(2))
1019                    .map_err(|e| ConversionError::IndexError(2, Box::new(e)))?;
1020                let b = B::try_from(items.remove(1))
1021                    .map_err(|e| ConversionError::IndexError(1, Box::new(e)))?;
1022                let a = A::try_from(items.remove(0))
1023                    .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
1024                Ok((a, b, c))
1025            }
1026            other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
1027        }
1028    }
1029}
1030
1031// 4-tuple
1032impl<A: Into<Value>, B: Into<Value>, C: Into<Value>, D: Into<Value>> From<(A, B, C, D)> for Value {
1033    fn from((a, b, c, d): (A, B, C, D)) -> Self {
1034        Value::Tuple(alloc::vec![a.into(), b.into(), c.into(), d.into()])
1035    }
1036}
1037
1038impl<
1039        A: TryFrom<Value, Error = ConversionError>,
1040        B: TryFrom<Value, Error = ConversionError>,
1041        C: TryFrom<Value, Error = ConversionError>,
1042        D: TryFrom<Value, Error = ConversionError>,
1043    > TryFrom<Value> for (A, B, C, D)
1044{
1045    type Error = ConversionError;
1046    fn try_from(v: Value) -> Result<Self, Self::Error> {
1047        match v {
1048            Value::Tuple(mut items) if items.len() == 4 => {
1049                let d = D::try_from(items.remove(3))
1050                    .map_err(|e| ConversionError::IndexError(3, Box::new(e)))?;
1051                let c = C::try_from(items.remove(2))
1052                    .map_err(|e| ConversionError::IndexError(2, Box::new(e)))?;
1053                let b = B::try_from(items.remove(1))
1054                    .map_err(|e| ConversionError::IndexError(1, Box::new(e)))?;
1055                let a = A::try_from(items.remove(0))
1056                    .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
1057                Ok((a, b, c, d))
1058            }
1059            other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
1060        }
1061    }
1062}
1063
1064// ============================================================================
1065// Result conversions (now using Value::Result directly)
1066// ============================================================================
1067
1068impl<T: Into<Value> + KnownValueType, E: Into<Value> + KnownValueType>
1069    From<core::result::Result<T, E>> for Value
1070{
1071    fn from(r: core::result::Result<T, E>) -> Self {
1072        let ok_type = T::known_value_type();
1073        let err_type = E::known_value_type();
1074        let value = match r {
1075            Ok(v) => Ok(Box::new(v.into())),
1076            Err(e) => Err(Box::new(e.into())),
1077        };
1078        Value::Result {
1079            ok_type,
1080            err_type,
1081            value,
1082        }
1083    }
1084}
1085
1086// Note: TryFrom<Value> for Result<T, E> is NOT implemented directly.
1087// Use FromValue::from_value() instead, which supports nested Option types.
1088// The FromValue impl for Result<T, E> is above with the other FromValue impls.
1089
1090use alloc::format;