1use alloc::boxed::Box;
4use alloc::collections::{BTreeMap, BTreeSet};
5use alloc::string::String;
6use alloc::vec::Vec;
7
8#[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), Variant(String), Tuple(Vec<ValueType>),
34 Flags,
35}
36
37#[derive(Debug, Clone, PartialEq)]
39#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
40pub enum Value {
41 Bool(bool),
43 U8(u8),
44 U16(u16),
45 U32(u32),
46 U64(u64),
47 S8(i8),
48 S16(i16),
49 S32(i32),
50 S64(i64),
51 F32(f32),
52 F64(f64),
53 Char(char),
54 String(String),
55
56 List {
58 elem_type: ValueType,
59 items: Vec<Value>,
60 },
61 Option {
62 inner_type: ValueType,
63 value: Option<Box<Value>>,
64 },
65 Result {
66 ok_type: ValueType,
67 err_type: ValueType,
68 value: core::result::Result<Box<Value>, Box<Value>>,
69 },
70 Record {
71 type_name: String,
72 fields: Vec<(String, Value)>,
73 },
74 Variant {
75 type_name: String,
76 case_name: String,
77 tag: usize,
78 payload: Vec<Value>,
79 },
80
81 Tuple(Vec<Value>),
83 Flags(u64),
84}
85
86impl Value {
87 pub fn sym(s: impl Into<String>) -> Self {
89 Value::Variant {
90 type_name: String::from("expr"),
91 case_name: String::from("sym"),
92 tag: 0,
93 payload: alloc::vec![Value::String(s.into())],
94 }
95 }
96
97 pub fn num(n: i64) -> Self {
99 Value::Variant {
100 type_name: String::from("expr"),
101 case_name: String::from("num"),
102 tag: 1,
103 payload: alloc::vec![Value::S64(n)],
104 }
105 }
106
107 pub fn lst(items: Vec<Value>) -> Self {
109 Value::Variant {
110 type_name: String::from("expr"),
111 case_name: String::from("lst"),
112 tag: 4,
113 payload: alloc::vec![Value::List {
114 elem_type: ValueType::Variant(String::from("expr")),
115 items,
116 }],
117 }
118 }
119
120 pub fn infer_type(&self) -> ValueType {
122 match self {
123 Value::Bool(_) => ValueType::Bool,
124 Value::U8(_) => ValueType::U8,
125 Value::U16(_) => ValueType::U16,
126 Value::U32(_) => ValueType::U32,
127 Value::U64(_) => ValueType::U64,
128 Value::S8(_) => ValueType::S8,
129 Value::S16(_) => ValueType::S16,
130 Value::S32(_) => ValueType::S32,
131 Value::S64(_) => ValueType::S64,
132 Value::F32(_) => ValueType::F32,
133 Value::F64(_) => ValueType::F64,
134 Value::Char(_) => ValueType::Char,
135 Value::String(_) => ValueType::String,
136 Value::List { elem_type, .. } => ValueType::List(Box::new(elem_type.clone())),
137 Value::Option { inner_type, .. } => ValueType::Option(Box::new(inner_type.clone())),
138 Value::Result {
139 ok_type, err_type, ..
140 } => ValueType::Result {
141 ok: Box::new(ok_type.clone()),
142 err: Box::new(err_type.clone()),
143 },
144 Value::Record { type_name, .. } => ValueType::Record(type_name.clone()),
145 Value::Variant { type_name, .. } => ValueType::Variant(type_name.clone()),
146 Value::Tuple(items) => ValueType::Tuple(items.iter().map(|v| v.infer_type()).collect()),
147 Value::Flags(_) => ValueType::Flags,
148 }
149 }
150}
151
152impl From<bool> for Value {
157 fn from(v: bool) -> Self {
158 Value::Bool(v)
159 }
160}
161
162impl From<u8> for Value {
163 fn from(v: u8) -> Self {
164 Value::U8(v)
165 }
166}
167
168impl From<u16> for Value {
169 fn from(v: u16) -> Self {
170 Value::U16(v)
171 }
172}
173
174impl From<u32> for Value {
175 fn from(v: u32) -> Self {
176 Value::U32(v)
177 }
178}
179
180impl From<u64> for Value {
181 fn from(v: u64) -> Self {
182 Value::U64(v)
183 }
184}
185
186impl From<i8> for Value {
187 fn from(v: i8) -> Self {
188 Value::S8(v)
189 }
190}
191
192impl From<i16> for Value {
193 fn from(v: i16) -> Self {
194 Value::S16(v)
195 }
196}
197
198impl From<i32> for Value {
199 fn from(v: i32) -> Self {
200 Value::S32(v)
201 }
202}
203
204impl From<i64> for Value {
205 fn from(v: i64) -> Self {
206 Value::S64(v)
207 }
208}
209
210impl From<f32> for Value {
211 fn from(v: f32) -> Self {
212 Value::F32(v)
213 }
214}
215
216impl From<f64> for Value {
217 fn from(v: f64) -> Self {
218 Value::F64(v)
219 }
220}
221
222impl From<char> for Value {
223 fn from(v: char) -> Self {
224 Value::Char(v)
225 }
226}
227
228impl From<String> for Value {
229 fn from(v: String) -> Self {
230 Value::String(v)
231 }
232}
233
234impl From<&str> for Value {
235 fn from(v: &str) -> Self {
236 Value::String(String::from(v))
237 }
238}
239
240impl<T: Into<Value>> From<Vec<T>> for Value {
241 fn from(v: Vec<T>) -> Self {
242 let items: Vec<Value> = v.into_iter().map(Into::into).collect();
243 let elem_type = items
245 .first()
246 .map(|v| v.infer_type())
247 .unwrap_or(ValueType::S32);
248 Value::List { elem_type, items }
249 }
250}
251
252impl<T: Into<Value>, const N: usize> From<[T; N]> for Value {
253 fn from(v: [T; N]) -> Self {
254 let items: Vec<Value> = v.into_iter().map(Into::into).collect();
255 let elem_type = items
256 .first()
257 .map(|v| v.infer_type())
258 .unwrap_or(ValueType::S32);
259 Value::List { elem_type, items }
260 }
261}
262
263impl<T: TryFrom<Value, Error = ConversionError>, const N: usize> TryFrom<Value> for [T; N] {
264 type Error = ConversionError;
265 fn try_from(v: Value) -> Result<Self, Self::Error> {
266 match v {
267 Value::List { items, .. } => {
268 if items.len() != N {
269 return Err(ConversionError::WrongFieldCount {
270 expected: N,
271 got: items.len(),
272 });
273 }
274 let vec: Vec<T> = items
275 .into_iter()
276 .enumerate()
277 .map(|(i, item)| {
278 T::try_from(item).map_err(|e| ConversionError::IndexError(i, Box::new(e)))
279 })
280 .collect::<Result<Vec<T>, _>>()?;
281 vec.try_into().map_err(|_| {
282 ConversionError::ExpectedList(String::from("array conversion failed"))
283 })
284 }
285 other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
286 }
287 }
288}
289
290impl<T: Into<Value>> From<Option<T>> for Value {
291 fn from(v: Option<T>) -> Self {
292 let (inner_type, value) = match v {
293 Some(x) => {
294 let val: Value = x.into();
295 let ty = val.infer_type();
296 (ty, Some(Box::new(val)))
297 }
298 None => (ValueType::S32, None), };
300 Value::Option { inner_type, value }
301 }
302}
303
304impl<T: Into<Value>> From<Box<T>> for Value {
305 fn from(v: Box<T>) -> Self {
306 (*v).into()
307 }
308}
309
310use crate::ConversionError;
315
316impl TryFrom<Value> for bool {
317 type Error = ConversionError;
318 fn try_from(v: Value) -> Result<Self, Self::Error> {
319 match v {
320 Value::Bool(x) => Ok(x),
321 other => Err(ConversionError::TypeMismatch {
322 expected: String::from("bool"),
323 got: format!("{:?}", other),
324 }),
325 }
326 }
327}
328
329impl TryFrom<Value> for u8 {
330 type Error = ConversionError;
331 fn try_from(v: Value) -> Result<Self, Self::Error> {
332 match v {
333 Value::U8(x) => Ok(x),
334 other => Err(ConversionError::TypeMismatch {
335 expected: String::from("u8"),
336 got: format!("{:?}", other),
337 }),
338 }
339 }
340}
341
342impl TryFrom<Value> for u16 {
343 type Error = ConversionError;
344 fn try_from(v: Value) -> Result<Self, Self::Error> {
345 match v {
346 Value::U16(x) => Ok(x),
347 other => Err(ConversionError::TypeMismatch {
348 expected: String::from("u16"),
349 got: format!("{:?}", other),
350 }),
351 }
352 }
353}
354
355impl TryFrom<Value> for u32 {
356 type Error = ConversionError;
357 fn try_from(v: Value) -> Result<Self, Self::Error> {
358 match v {
359 Value::U32(x) => Ok(x),
360 other => Err(ConversionError::TypeMismatch {
361 expected: String::from("u32"),
362 got: format!("{:?}", other),
363 }),
364 }
365 }
366}
367
368impl TryFrom<Value> for u64 {
369 type Error = ConversionError;
370 fn try_from(v: Value) -> Result<Self, Self::Error> {
371 match v {
372 Value::U64(x) => Ok(x),
373 other => Err(ConversionError::TypeMismatch {
374 expected: String::from("u64"),
375 got: format!("{:?}", other),
376 }),
377 }
378 }
379}
380
381impl TryFrom<Value> for i8 {
382 type Error = ConversionError;
383 fn try_from(v: Value) -> Result<Self, Self::Error> {
384 match v {
385 Value::S8(x) => Ok(x),
386 other => Err(ConversionError::TypeMismatch {
387 expected: String::from("i8"),
388 got: format!("{:?}", other),
389 }),
390 }
391 }
392}
393
394impl TryFrom<Value> for i16 {
395 type Error = ConversionError;
396 fn try_from(v: Value) -> Result<Self, Self::Error> {
397 match v {
398 Value::S16(x) => Ok(x),
399 other => Err(ConversionError::TypeMismatch {
400 expected: String::from("i16"),
401 got: format!("{:?}", other),
402 }),
403 }
404 }
405}
406
407impl TryFrom<Value> for i32 {
408 type Error = ConversionError;
409 fn try_from(v: Value) -> Result<Self, Self::Error> {
410 match v {
411 Value::S32(x) => Ok(x),
412 other => Err(ConversionError::TypeMismatch {
413 expected: String::from("i32"),
414 got: format!("{:?}", other),
415 }),
416 }
417 }
418}
419
420impl TryFrom<Value> for i64 {
421 type Error = ConversionError;
422 fn try_from(v: Value) -> Result<Self, Self::Error> {
423 match v {
424 Value::S64(x) => Ok(x),
425 other => Err(ConversionError::TypeMismatch {
426 expected: String::from("i64"),
427 got: format!("{:?}", other),
428 }),
429 }
430 }
431}
432
433impl TryFrom<Value> for f32 {
434 type Error = ConversionError;
435 fn try_from(v: Value) -> Result<Self, Self::Error> {
436 match v {
437 Value::F32(x) => Ok(x),
438 other => Err(ConversionError::TypeMismatch {
439 expected: String::from("f32"),
440 got: format!("{:?}", other),
441 }),
442 }
443 }
444}
445
446impl TryFrom<Value> for f64 {
447 type Error = ConversionError;
448 fn try_from(v: Value) -> Result<Self, Self::Error> {
449 match v {
450 Value::F64(x) => Ok(x),
451 other => Err(ConversionError::TypeMismatch {
452 expected: String::from("f64"),
453 got: format!("{:?}", other),
454 }),
455 }
456 }
457}
458
459impl TryFrom<Value> for char {
460 type Error = ConversionError;
461 fn try_from(v: Value) -> Result<Self, Self::Error> {
462 match v {
463 Value::Char(x) => Ok(x),
464 other => Err(ConversionError::TypeMismatch {
465 expected: String::from("char"),
466 got: format!("{:?}", other),
467 }),
468 }
469 }
470}
471
472impl TryFrom<Value> for String {
473 type Error = ConversionError;
474 fn try_from(v: Value) -> Result<Self, Self::Error> {
475 match v {
476 Value::String(x) => Ok(x),
477 other => Err(ConversionError::TypeMismatch {
478 expected: String::from("String"),
479 got: format!("{:?}", other),
480 }),
481 }
482 }
483}
484
485impl<T: TryFrom<Value, Error = ConversionError>> TryFrom<Value> for Vec<T> {
486 type Error = ConversionError;
487 fn try_from(v: Value) -> Result<Self, Self::Error> {
488 match v {
489 Value::List { items, .. } => items
490 .into_iter()
491 .enumerate()
492 .map(|(i, item)| {
493 T::try_from(item).map_err(|e| ConversionError::IndexError(i, Box::new(e)))
494 })
495 .collect(),
496 other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
497 }
498 }
499}
500
501impl<T: Into<Value> + Ord> From<BTreeSet<T>> for Value {
502 fn from(v: BTreeSet<T>) -> Self {
503 let items: Vec<Value> = v.into_iter().map(Into::into).collect();
504 let elem_type = items
505 .first()
506 .map(|v| v.infer_type())
507 .unwrap_or(ValueType::S32);
508 Value::List { elem_type, items }
509 }
510}
511
512impl<T: TryFrom<Value, Error = ConversionError> + Ord> TryFrom<Value> for BTreeSet<T> {
513 type Error = ConversionError;
514 fn try_from(v: Value) -> Result<Self, Self::Error> {
515 match v {
516 Value::List { items, .. } => items
517 .into_iter()
518 .enumerate()
519 .map(|(i, item)| {
520 T::try_from(item).map_err(|e| ConversionError::IndexError(i, Box::new(e)))
521 })
522 .collect(),
523 other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
524 }
525 }
526}
527
528impl<K: Into<Value> + Ord, V: Into<Value>> From<BTreeMap<K, V>> for Value {
529 fn from(v: BTreeMap<K, V>) -> Self {
530 let items: Vec<Value> = v
531 .into_iter()
532 .map(|(k, v)| Value::Tuple(Vec::from([k.into(), v.into()])))
533 .collect();
534 let elem_type = items
535 .first()
536 .map(|v| v.infer_type())
537 .unwrap_or(ValueType::S32);
538 Value::List { elem_type, items }
539 }
540}
541
542impl<
543 K: TryFrom<Value, Error = ConversionError> + Ord,
544 V: TryFrom<Value, Error = ConversionError>,
545 > TryFrom<Value> for BTreeMap<K, V>
546{
547 type Error = ConversionError;
548 fn try_from(v: Value) -> Result<Self, Self::Error> {
549 match v {
550 Value::List { items, .. } => items
551 .into_iter()
552 .enumerate()
553 .map(|(i, item)| match item {
554 Value::Tuple(mut fields) if fields.len() == 2 => {
555 let v_val = fields.pop().unwrap();
556 let k_val = fields.pop().unwrap();
557 let k = K::try_from(k_val)
558 .map_err(|e| ConversionError::IndexError(i, Box::new(e)))?;
559 let v = V::try_from(v_val)
560 .map_err(|e| ConversionError::IndexError(i, Box::new(e)))?;
561 Ok((k, v))
562 }
563 other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
564 })
565 .collect(),
566 other => Err(ConversionError::ExpectedList(format!("{:?}", other))),
567 }
568 }
569}
570
571pub trait FromValue: Sized {
581 fn from_value(v: Value) -> Result<Self, ConversionError>;
582}
583
584impl<T: TryFrom<Value, Error = ConversionError>> FromValue for T {
586 fn from_value(v: Value) -> Result<Self, ConversionError> {
587 T::try_from(v)
588 }
589}
590
591impl FromValue for Value {
593 fn from_value(v: Value) -> Result<Self, ConversionError> {
594 Ok(v)
595 }
596}
597
598impl<T: FromValue> FromValue for Option<T> {
600 fn from_value(v: Value) -> Result<Self, ConversionError> {
601 match v {
602 Value::Option { value: None, .. } => Ok(None),
603 Value::Option {
604 value: Some(inner), ..
605 } => {
606 let value = T::from_value(*inner)?;
607 Ok(Some(value))
608 }
609 other => Err(ConversionError::ExpectedOption(format!("{:?}", other))),
610 }
611 }
612}
613
614impl<T: FromValue, E: FromValue> FromValue for core::result::Result<T, E> {
616 fn from_value(v: Value) -> Result<Self, ConversionError> {
617 match v {
618 Value::Result {
619 value: Ok(inner), ..
620 } => {
621 let value = T::from_value(*inner)
622 .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
623 Ok(Ok(value))
624 }
625 Value::Result {
626 value: Err(inner), ..
627 } => {
628 let value = E::from_value(*inner)
629 .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
630 Ok(Err(value))
631 }
632 Value::Variant {
634 tag: 0, payload, ..
635 } if !payload.is_empty() => {
636 let value = T::from_value(payload.into_iter().next().unwrap())
637 .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
638 Ok(Ok(value))
639 }
640 Value::Variant {
641 tag: 1, payload, ..
642 } if !payload.is_empty() => {
643 let value = E::from_value(payload.into_iter().next().unwrap())
644 .map_err(|e| ConversionError::PayloadError(Box::new(e)))?;
645 Ok(Err(value))
646 }
647 Value::Variant { tag, .. } => Err(ConversionError::UnknownTag { tag, max: 1 }),
648 other => Err(ConversionError::ExpectedVariant(format!("{:?}", other))),
649 }
650 }
651}
652
653impl From<()> for Value {
659 fn from(_: ()) -> Self {
660 Value::Tuple(Vec::new())
661 }
662}
663
664impl TryFrom<Value> for () {
665 type Error = ConversionError;
666 fn try_from(v: Value) -> Result<Self, Self::Error> {
667 match v {
668 Value::Tuple(items) if items.is_empty() => Ok(()),
669 other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
670 }
671 }
672}
673
674impl<A: Into<Value>> From<(A,)> for Value {
676 fn from((a,): (A,)) -> Self {
677 Value::Tuple(alloc::vec![a.into()])
678 }
679}
680
681impl<A: TryFrom<Value, Error = ConversionError>> TryFrom<Value> for (A,) {
682 type Error = ConversionError;
683 fn try_from(v: Value) -> Result<Self, Self::Error> {
684 match v {
685 Value::Tuple(mut items) if items.len() == 1 => {
686 let a = A::try_from(items.remove(0))
687 .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
688 Ok((a,))
689 }
690 other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
691 }
692 }
693}
694
695impl<A: Into<Value>, B: Into<Value>> From<(A, B)> for Value {
697 fn from((a, b): (A, B)) -> Self {
698 Value::Tuple(alloc::vec![a.into(), b.into()])
699 }
700}
701
702impl<A: TryFrom<Value, Error = ConversionError>, B: TryFrom<Value, Error = ConversionError>>
703 TryFrom<Value> for (A, B)
704{
705 type Error = ConversionError;
706 fn try_from(v: Value) -> Result<Self, Self::Error> {
707 match v {
708 Value::Tuple(mut items) if items.len() == 2 => {
709 let b = B::try_from(items.remove(1))
710 .map_err(|e| ConversionError::IndexError(1, Box::new(e)))?;
711 let a = A::try_from(items.remove(0))
712 .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
713 Ok((a, b))
714 }
715 other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
716 }
717 }
718}
719
720impl<A: Into<Value>, B: Into<Value>, C: Into<Value>> From<(A, B, C)> for Value {
722 fn from((a, b, c): (A, B, C)) -> Self {
723 Value::Tuple(alloc::vec![a.into(), b.into(), c.into()])
724 }
725}
726
727impl<
728 A: TryFrom<Value, Error = ConversionError>,
729 B: TryFrom<Value, Error = ConversionError>,
730 C: TryFrom<Value, Error = ConversionError>,
731 > TryFrom<Value> for (A, B, C)
732{
733 type Error = ConversionError;
734 fn try_from(v: Value) -> Result<Self, Self::Error> {
735 match v {
736 Value::Tuple(mut items) if items.len() == 3 => {
737 let c = C::try_from(items.remove(2))
738 .map_err(|e| ConversionError::IndexError(2, Box::new(e)))?;
739 let b = B::try_from(items.remove(1))
740 .map_err(|e| ConversionError::IndexError(1, Box::new(e)))?;
741 let a = A::try_from(items.remove(0))
742 .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
743 Ok((a, b, c))
744 }
745 other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
746 }
747 }
748}
749
750impl<A: Into<Value>, B: Into<Value>, C: Into<Value>, D: Into<Value>> From<(A, B, C, D)> for Value {
752 fn from((a, b, c, d): (A, B, C, D)) -> Self {
753 Value::Tuple(alloc::vec![a.into(), b.into(), c.into(), d.into()])
754 }
755}
756
757impl<
758 A: TryFrom<Value, Error = ConversionError>,
759 B: TryFrom<Value, Error = ConversionError>,
760 C: TryFrom<Value, Error = ConversionError>,
761 D: TryFrom<Value, Error = ConversionError>,
762 > TryFrom<Value> for (A, B, C, D)
763{
764 type Error = ConversionError;
765 fn try_from(v: Value) -> Result<Self, Self::Error> {
766 match v {
767 Value::Tuple(mut items) if items.len() == 4 => {
768 let d = D::try_from(items.remove(3))
769 .map_err(|e| ConversionError::IndexError(3, Box::new(e)))?;
770 let c = C::try_from(items.remove(2))
771 .map_err(|e| ConversionError::IndexError(2, Box::new(e)))?;
772 let b = B::try_from(items.remove(1))
773 .map_err(|e| ConversionError::IndexError(1, Box::new(e)))?;
774 let a = A::try_from(items.remove(0))
775 .map_err(|e| ConversionError::IndexError(0, Box::new(e)))?;
776 Ok((a, b, c, d))
777 }
778 other => Err(ConversionError::ExpectedTuple(format!("{:?}", other))),
779 }
780 }
781}
782
783impl<T: Into<Value>, E: Into<Value>> From<core::result::Result<T, E>> for Value {
788 fn from(r: core::result::Result<T, E>) -> Self {
789 match r {
790 Ok(v) => {
791 let val: Value = v.into();
792 let ok_type = val.infer_type();
793 Value::Result {
794 ok_type,
795 err_type: ValueType::String, value: Ok(Box::new(val)),
797 }
798 }
799 Err(e) => {
800 let val: Value = e.into();
801 let err_type = val.infer_type();
802 Value::Result {
803 ok_type: ValueType::S32, err_type,
805 value: Err(Box::new(val)),
806 }
807 }
808 }
809 }
810}
811
812use alloc::format;