kittycad_execution_plan_traits/
primitive.rs1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4use crate::{impl_value_on_primitive_ish, Address, MemoryError, Value};
5
6#[derive(PartialEq, Clone, Serialize, Deserialize)]
8pub enum Primitive {
9 String(String),
11 NumericValue(NumericPrimitive),
13 Uuid(Uuid),
15 Bytes(Vec<u8>),
17 Bool(bool),
19 ListHeader(ListHeader),
21 ObjectHeader(ObjectHeader),
23 Nil,
25 Address(Address),
27}
28
29impl std::fmt::Debug for Primitive {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 Primitive::String(s) => write!(f, r#""{s}""#),
33 Primitive::NumericValue(NumericPrimitive::Float(x)) => x.fmt(f),
34 Primitive::NumericValue(NumericPrimitive::Integer(x)) => x.fmt(f),
35 Primitive::NumericValue(NumericPrimitive::UInteger(x)) => write!(f, "{x} (uint)"),
36 Primitive::Uuid(u) => write!(f, "{u}"),
37 Primitive::Bytes(_) => write!(f, "Binary"),
38 Primitive::Bool(b) => write!(f, "{b}"),
39 Primitive::ListHeader(ListHeader { count, size }) => write!(f, "List header (count {count}, size {size})"),
40 Primitive::ObjectHeader(ObjectHeader { properties, size }) => {
41 write!(f, "Object header (props {properties:?}, size {size})")
42 }
43 Primitive::Nil => write!(f, "Nil"),
44 Primitive::Address(a) => write!(f, "Addr({})", a.0),
45 }
46 }
47}
48
49#[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize, Debug)]
53pub struct ListHeader {
54 pub count: usize,
56 pub size: usize,
58}
59
60#[derive(Clone, Eq, PartialEq, Deserialize, Serialize, Debug)]
64pub struct ObjectHeader {
65 pub properties: Vec<String>,
67 pub size: usize,
69}
70
71impl From<bool> for Primitive {
72 fn from(value: bool) -> Self {
73 Self::Bool(value)
74 }
75}
76
77impl From<Uuid> for Primitive {
78 fn from(u: Uuid) -> Self {
79 Self::Uuid(u)
80 }
81}
82
83impl From<String> for Primitive {
84 fn from(value: String) -> Self {
85 Self::String(value)
86 }
87}
88
89impl From<f32> for Primitive {
90 fn from(value: f32) -> Self {
91 Self::NumericValue(NumericPrimitive::Float(value as f64))
92 }
93}
94
95impl From<f64> for Primitive {
96 fn from(value: f64) -> Self {
97 Self::NumericValue(NumericPrimitive::Float(value))
98 }
99}
100
101impl From<Vec<u8>> for Primitive {
102 fn from(value: Vec<u8>) -> Self {
103 Self::Bytes(value)
104 }
105}
106
107impl From<ListHeader> for Primitive {
108 fn from(value: ListHeader) -> Self {
109 Self::ListHeader(value)
110 }
111}
112
113impl From<ObjectHeader> for Primitive {
114 fn from(value: ObjectHeader) -> Self {
115 Self::ObjectHeader(value)
116 }
117}
118
119impl From<Address> for Primitive {
120 fn from(value: Address) -> Self {
121 Self::Address(value)
122 }
123}
124
125impl TryFrom<Primitive> for String {
126 type Error = MemoryError;
127
128 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
129 if let Primitive::String(s) = value {
130 Ok(s)
131 } else {
132 Err(MemoryError::MemoryWrongType {
133 expected: "string",
134 actual: format!("{value:?}"),
135 })
136 }
137 }
138}
139
140impl TryFrom<Primitive> for Uuid {
141 type Error = MemoryError;
142
143 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
144 if let Primitive::Uuid(u) = value {
145 Ok(u)
146 } else {
147 Err(MemoryError::MemoryWrongType {
148 expected: "uuid",
149 actual: format!("{value:?}"),
150 })
151 }
152 }
153}
154
155impl TryFrom<Primitive> for f64 {
156 type Error = MemoryError;
157
158 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
159 if let Primitive::NumericValue(NumericPrimitive::Float(x)) = value {
160 Ok(x)
161 } else {
162 Err(MemoryError::MemoryWrongType {
163 expected: "float",
164 actual: format!("{value:?}"),
165 })
166 }
167 }
168}
169
170impl TryFrom<Primitive> for f32 {
171 type Error = MemoryError;
172
173 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
174 f64::try_from(value).map(|x| x as f32)
175 }
176}
177
178impl TryFrom<Primitive> for Vec<u8> {
179 type Error = MemoryError;
180
181 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
182 if let Primitive::Bytes(x) = value {
183 Ok(x)
184 } else {
185 Err(MemoryError::MemoryWrongType {
186 expected: "bytes",
187 actual: format!("{value:?}"),
188 })
189 }
190 }
191}
192
193impl TryFrom<Primitive> for bool {
194 type Error = MemoryError;
195
196 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
197 if let Primitive::Bool(x) = value {
198 Ok(x)
199 } else {
200 Err(MemoryError::MemoryWrongType {
201 expected: "bool",
202 actual: format!("{value:?}"),
203 })
204 }
205 }
206}
207
208impl TryFrom<Primitive> for Address {
209 type Error = MemoryError;
210
211 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
212 if let Primitive::Address(x) = value {
213 Ok(x)
214 } else {
215 Err(MemoryError::MemoryWrongType {
216 expected: "address",
217 actual: format!("{value:?}"),
218 })
219 }
220 }
221}
222
223impl TryFrom<Primitive> for usize {
224 type Error = MemoryError;
225
226 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
227 if let Primitive::NumericValue(NumericPrimitive::UInteger(x)) = value {
228 Ok(x)
229 } else {
230 Err(MemoryError::MemoryWrongType {
231 expected: "usize",
232 actual: format!("{value:?}"),
233 })
234 }
235 }
236}
237
238impl TryFrom<Primitive> for u32 {
239 type Error = MemoryError;
240
241 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
242 if let Primitive::NumericValue(NumericPrimitive::UInteger(x)) = value {
243 Ok(x.try_into().map_err(|_| MemoryError::MemoryWrongType {
244 expected: "u32",
245 actual: x.to_string(),
246 })?)
247 } else {
248 Err(MemoryError::MemoryWrongType {
249 expected: "u32",
250 actual: format!("{value:?}"),
251 })
252 }
253 }
254}
255
256impl TryFrom<Primitive> for ListHeader {
257 type Error = MemoryError;
258
259 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
260 if let Primitive::ListHeader(x) = value {
261 Ok(x)
262 } else {
263 Err(MemoryError::MemoryWrongType {
264 expected: "ListHeader",
265 actual: format!("{value:?}"),
266 })
267 }
268 }
269}
270
271impl TryFrom<Primitive> for ObjectHeader {
272 type Error = MemoryError;
273
274 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
275 if let Primitive::ObjectHeader(x) = value {
276 Ok(x)
277 } else {
278 Err(MemoryError::MemoryWrongType {
279 expected: "ObjectHeader",
280 actual: format!("{value:?}"),
281 })
282 }
283 }
284}
285
286impl TryFrom<Primitive> for i64 {
287 type Error = MemoryError;
288
289 fn try_from(value: Primitive) -> Result<Self, Self::Error> {
290 if let Primitive::NumericValue(NumericPrimitive::Integer(x)) = value {
291 Ok(x)
292 } else {
293 Err(MemoryError::MemoryWrongType {
294 expected: "i64",
295 actual: format!("{value:?}"),
296 })
297 }
298 }
299}
300
301impl From<usize> for Primitive {
302 fn from(value: usize) -> Self {
303 Self::NumericValue(NumericPrimitive::UInteger(value))
304 }
305}
306
307impl From<u32> for Primitive {
308 fn from(value: u32) -> Self {
309 Self::NumericValue(NumericPrimitive::UInteger(value as usize))
310 }
311}
312
313impl From<i64> for Primitive {
314 fn from(value: i64) -> Self {
315 Self::NumericValue(NumericPrimitive::Integer(value))
316 }
317}
318
319#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
321pub enum NumericPrimitive {
322 UInteger(usize),
324 Integer(i64),
326 Float(f64),
328}
329
330impl crate::Value for Primitive {
331 fn into_parts(self) -> Vec<Primitive> {
332 vec![self]
333 }
334
335 fn from_parts<I>(values: &mut I) -> Result<(Self, usize), MemoryError>
336 where
337 I: Iterator<Item = Option<Primitive>>,
338 {
339 values
340 .next()
341 .and_then(|v| v.to_owned())
342 .ok_or(MemoryError::MemoryWrongSize)
343 .map(|prim| (prim, 1))
344 }
345}
346
347impl From<NumericPrimitive> for f64 {
348 fn from(value: NumericPrimitive) -> Self {
349 match value {
350 NumericPrimitive::UInteger(x) => x as f64,
351 NumericPrimitive::Integer(x) => x as f64,
352 NumericPrimitive::Float(x) => x,
353 }
354 }
355}
356
357impl_value_on_primitive_ish!(Value, f32);
358impl_value_on_primitive_ish!(Value, f64);
359impl_value_on_primitive_ish!(Value, bool);
360impl_value_on_primitive_ish!(Value, String);
361impl_value_on_primitive_ish!(Value, Uuid);
362type VecU8 = Vec<u8>;
363impl_value_on_primitive_ish!(Value, VecU8);
364impl_value_on_primitive_ish!(Value, usize);
365impl_value_on_primitive_ish!(Value, u32);
366impl_value_on_primitive_ish!(Value, i64);