Skip to main content

lutra_bin/value/
fold.rs

1use crate::ir;
2
3use crate::Error;
4use crate::Value;
5
6pub trait ValueVisitor<'t> {
7    type Res;
8
9    fn get_ty(&self, name: &ir::Path) -> &'t ir::Ty;
10
11    fn get_mat_ty(&self, ty: &'t ir::Ty) -> &'t ir::Ty {
12        let mut ty = ty;
13        while let ir::TyKind::Ident(name) = &ty.kind {
14            ty = self.get_ty(name);
15        }
16        ty
17    }
18
19    fn visit_value(&mut self, value: &Value, ty: &'t ir::Ty) -> Result<Self::Res, crate::Error> {
20        let ty = self.get_mat_ty(ty);
21
22        match &ty.kind {
23            ir::TyKind::Primitive(ir::TyPrimitive::bool) => {
24                self.visit_bool(value.expect_prim8()? != 0)
25            }
26            ir::TyKind::Primitive(ir::TyPrimitive::int8) => {
27                self.visit_int8(value.expect_prim8()? as i8)
28            }
29            ir::TyKind::Primitive(ir::TyPrimitive::uint8) => {
30                self.visit_uint8(value.expect_prim8()?)
31            }
32            ir::TyKind::Primitive(ir::TyPrimitive::int16) => {
33                self.visit_int16(value.expect_prim16()? as i16)
34            }
35            ir::TyKind::Primitive(ir::TyPrimitive::uint16) => {
36                self.visit_uint16(value.expect_prim16()?)
37            }
38            ir::TyKind::Primitive(ir::TyPrimitive::int32) => {
39                self.visit_int32(value.expect_prim32()? as i32)
40            }
41            ir::TyKind::Primitive(ir::TyPrimitive::uint32) => {
42                self.visit_uint32(value.expect_prim32()?)
43            }
44            ir::TyKind::Primitive(ir::TyPrimitive::float32) => {
45                self.visit_float32(f32::from_ne_bytes(value.expect_prim32()?.to_ne_bytes()))
46            }
47            ir::TyKind::Primitive(ir::TyPrimitive::int64) => {
48                self.visit_int64(value.expect_prim64()? as i64)
49            }
50            ir::TyKind::Primitive(ir::TyPrimitive::uint64) => {
51                self.visit_uint64(value.expect_prim64()?)
52            }
53            ir::TyKind::Primitive(ir::TyPrimitive::float64) => {
54                self.visit_float64(f64::from_ne_bytes(value.expect_prim64()?.to_ne_bytes()))
55            }
56            ir::TyKind::Primitive(ir::TyPrimitive::text) => self.visit_text(value.expect_text()?),
57            ir::TyKind::Tuple(ty_fields) => {
58                let fields = value.expect_tuple()?;
59                self.visit_tuple(fields, ty_fields)
60            }
61            ir::TyKind::Array(ty_items) => {
62                let items = value.expect_array()?;
63                self.visit_array(items, ty_items)
64            }
65            ir::TyKind::Enum(variants) => {
66                let (tag, inner) = value.expect_enum()?;
67                self.visit_enum(tag, inner, variants)
68            }
69
70            ir::TyKind::Function(..) => Err(Error::InvalidType),
71            ir::TyKind::Ident(..) => Err(Error::Bug),
72        }
73    }
74
75    fn visit_bool(&mut self, v: bool) -> Result<Self::Res, crate::Error>;
76    fn visit_int8(&mut self, v: i8) -> Result<Self::Res, crate::Error>;
77    fn visit_int16(&mut self, v: i16) -> Result<Self::Res, crate::Error>;
78    fn visit_int32(&mut self, v: i32) -> Result<Self::Res, crate::Error>;
79    fn visit_int64(&mut self, v: i64) -> Result<Self::Res, crate::Error>;
80    fn visit_uint8(&mut self, v: u8) -> Result<Self::Res, crate::Error>;
81    fn visit_uint16(&mut self, v: u16) -> Result<Self::Res, crate::Error>;
82    fn visit_uint32(&mut self, v: u32) -> Result<Self::Res, crate::Error>;
83    fn visit_uint64(&mut self, v: u64) -> Result<Self::Res, crate::Error>;
84    fn visit_float32(&mut self, v: f32) -> Result<Self::Res, crate::Error>;
85    fn visit_float64(&mut self, v: f64) -> Result<Self::Res, crate::Error>;
86    fn visit_text(&mut self, v: &str) -> Result<Self::Res, crate::Error>;
87
88    fn visit_tuple(
89        &mut self,
90        fields: &[Value],
91        ty_fields: &'t [ir::TyTupleField],
92    ) -> Result<Self::Res, crate::Error>;
93
94    fn visit_array(
95        &mut self,
96        items: &[Value],
97        ty_items: &'t ir::Ty,
98    ) -> Result<Self::Res, crate::Error>;
99
100    fn visit_enum(
101        &mut self,
102        tag: usize,
103        inner: &Value,
104        ty_variants: &'t [ir::TyEnumVariant],
105    ) -> Result<Self::Res, crate::Error>;
106}