1mod decode;
11mod encode;
12mod fold;
13mod print_source;
14
15pub use fold::ValueVisitor;
16
17use crate::{boxed, string, vec};
18
19use crate::ir;
20use crate::{Error, Result};
21
22#[derive(Clone, Debug, PartialEq)]
24pub enum Value {
25 Prim8(u8),
26 Prim16(u16),
27 Prim32(u32),
28 Prim64(u64),
29
30 Tuple(vec::Vec<Value>),
31 Array(vec::Vec<Value>),
32 Enum(usize, boxed::Box<Value>),
33}
34
35impl Value {
36 pub fn unit() -> Value {
37 Value::Tuple(vec![])
38 }
39
40 pub fn expect_prim8(&self) -> Result<u8> {
41 match self {
42 Value::Prim8(value) => Ok(*value),
43 _ => Err(Error::BadValueType {
44 expected: "Prim8",
45 found: self.name(),
46 }),
47 }
48 }
49
50 pub fn expect_prim16(&self) -> Result<u16> {
51 match self {
52 Value::Prim16(value) => Ok(*value),
53 _ => Err(Error::BadValueType {
54 expected: "Prim16",
55 found: self.name(),
56 }),
57 }
58 }
59
60 pub fn expect_prim32(&self) -> Result<u32> {
61 match self {
62 Value::Prim32(value) => Ok(*value),
63 _ => Err(Error::BadValueType {
64 expected: "Prim32",
65 found: self.name(),
66 }),
67 }
68 }
69
70 pub fn expect_prim64(&self) -> Result<u64> {
71 match self {
72 Value::Prim64(value) => Ok(*value),
73 _ => Err(Error::BadValueType {
74 expected: "Prim64",
75 found: self.name(),
76 }),
77 }
78 }
79
80 pub fn new_text(s: &str) -> Value {
81 Value::Array(s.bytes().map(Value::Prim8).collect())
82 }
83
84 pub fn expect_text_cloned(&self) -> Result<string::String> {
85 match self {
86 Value::Array(bytes) => {
87 let bytes: vec::Vec<u8> = bytes
88 .iter()
89 .map(|v| v.expect_prim8())
90 .collect::<Result<_>>()?;
91 string::String::from_utf8(bytes).map_err(|_| Error::InvalidData)
92 }
93 _ => Err(Error::BadValueType {
94 expected: "Text",
95 found: self.name(),
96 }),
97 }
98 }
99
100 pub fn expect_tuple(&self) -> Result<&[Value]> {
101 match self {
102 Value::Tuple(value) => Ok(value),
103 _ => Err(Error::BadValueType {
104 expected: "Tuple",
105 found: self.name(),
106 }),
107 }
108 }
109
110 pub fn expect_array(&self) -> Result<&[Value]> {
111 match self {
112 Value::Array(value) => Ok(value),
113 _ => Err(Error::BadValueType {
114 expected: "Array",
115 found: self.name(),
116 }),
117 }
118 }
119
120 pub fn expect_enum(&self) -> Result<(usize, &Value)> {
121 match self {
122 Value::Enum(tag, inner) => Ok((*tag, inner)),
123 _ => Err(Error::BadValueType {
124 expected: "Enum",
125 found: self.name(),
126 }),
127 }
128 }
129
130 fn name(&self) -> &'static str {
131 match self {
132 Value::Prim8(..) => "Prim8",
133 Value::Prim16(..) => "Prim16",
134 Value::Prim32(..) => "Prim32",
135 Value::Prim64(..) => "Prim64",
136 Value::Tuple(..) => "Tuple",
137 Value::Array(..) => "Array",
138 Value::Enum(..) => "Enum",
139 }
140 }
141}
142
143#[derive(Clone, Copy, Debug, PartialEq)]
144enum TyClass<'t> {
145 Prim8,
146 Prim16,
147 Prim32,
148 Prim64,
149 Tuple(&'t [ir::TyTupleField]),
150 Array(&'t ir::Ty),
151 Enum(&'t [ir::TyEnumVariant]),
152}
153
154impl<'t> TyClass<'t> {
155 fn of_ty(ty_mat: &'t ir::Ty) -> Result<Self> {
156 Ok(match &ty_mat.kind {
157 ir::TyKind::Primitive(ir::TyPrimitive::Prim8) => TyClass::Prim8,
158 ir::TyKind::Primitive(ir::TyPrimitive::Prim16) => TyClass::Prim16,
159 ir::TyKind::Primitive(ir::TyPrimitive::Prim32) => TyClass::Prim32,
160 ir::TyKind::Primitive(ir::TyPrimitive::Prim64) => TyClass::Prim64,
161
162 ir::TyKind::Tuple(t) => TyClass::Tuple(t),
163 ir::TyKind::Array(t) => TyClass::Array(t),
164 ir::TyKind::Enum(t) => TyClass::Enum(t),
165
166 ir::TyKind::Function(..) => return Err(Error::InvalidType),
167 ir::TyKind::Ident(..) => return Err(Error::Bug),
168 })
169 }
170}