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}