nodedb_types/value/
msgpack.rs1use std::collections::HashMap;
9use std::sync::Arc;
10
11use super::core::Value;
12use crate::array_cell::ArrayCell;
13use crate::datetime::{NdbDateTime, NdbDuration};
14use crate::geometry::Geometry;
15
16impl zerompk::ToMessagePack for Value {
17 fn write<W: zerompk::Write>(&self, writer: &mut W) -> zerompk::Result<()> {
18 match self {
19 Value::Null => {
20 writer.write_array_len(1)?;
21 writer.write_u8(0)
22 }
23 Value::Bool(b) => {
24 writer.write_array_len(2)?;
25 writer.write_u8(1)?;
26 writer.write_boolean(*b)
27 }
28 Value::Integer(i) => {
29 writer.write_array_len(2)?;
30 writer.write_u8(2)?;
31 writer.write_i64(*i)
32 }
33 Value::Float(f) => {
34 writer.write_array_len(2)?;
35 writer.write_u8(3)?;
36 writer.write_f64(*f)
37 }
38 Value::String(s) => {
39 writer.write_array_len(2)?;
40 writer.write_u8(4)?;
41 writer.write_string(s)
42 }
43 Value::Bytes(b) => {
44 writer.write_array_len(2)?;
45 writer.write_u8(5)?;
46 writer.write_binary(b)
47 }
48 Value::Array(arr) => {
49 writer.write_array_len(2)?;
50 writer.write_u8(6)?;
51 arr.write(writer)
52 }
53 Value::Object(map) => {
54 writer.write_array_len(2)?;
55 writer.write_u8(7)?;
56 map.write(writer)
57 }
58 Value::Uuid(s) => {
59 writer.write_array_len(2)?;
60 writer.write_u8(8)?;
61 writer.write_string(s)
62 }
63 Value::Ulid(s) => {
64 writer.write_array_len(2)?;
65 writer.write_u8(9)?;
66 writer.write_string(s)
67 }
68 Value::DateTime(dt) => {
69 writer.write_array_len(2)?;
70 writer.write_u8(10)?;
71 dt.write(writer)
72 }
73 Value::Duration(d) => {
74 writer.write_array_len(2)?;
75 writer.write_u8(11)?;
76 d.write(writer)
77 }
78 Value::Decimal(d) => {
79 writer.write_array_len(2)?;
80 writer.write_u8(12)?;
81 writer.write_binary(&d.serialize())
82 }
83 Value::Geometry(g) => {
84 writer.write_array_len(2)?;
85 writer.write_u8(13)?;
86 g.write(writer)
87 }
88 Value::Set(s) => {
89 writer.write_array_len(2)?;
90 writer.write_u8(14)?;
91 s.write(writer)
92 }
93 Value::Regex(r) => {
94 writer.write_array_len(2)?;
95 writer.write_u8(15)?;
96 writer.write_string(r)
97 }
98 Value::Range {
99 start,
100 end,
101 inclusive,
102 } => {
103 writer.write_array_len(4)?;
104 writer.write_u8(16)?;
105 start.write(writer)?;
106 end.write(writer)?;
107 writer.write_boolean(*inclusive)
108 }
109 Value::Record { table, id } => {
110 writer.write_array_len(3)?;
111 writer.write_u8(17)?;
112 writer.write_string(table)?;
113 writer.write_string(id)
114 }
115 Value::ArrayCell(cell) => {
116 writer.write_array_len(2)?;
117 writer.write_u8(18)?;
118 cell.write(writer)
119 }
120 Value::NaiveDateTime(dt) => {
121 writer.write_array_len(2)?;
122 writer.write_u8(19)?;
123 dt.write(writer)
124 }
125 Value::Vector(v) => {
126 writer.write_array_len(2)?;
127 writer.write_u8(20)?;
128 writer.write_binary(bytemuck::cast_slice(v.as_ref()))
129 }
130 }
131 }
132}
133
134impl<'a> zerompk::FromMessagePack<'a> for Value {
135 fn read<R: zerompk::Read<'a>>(reader: &mut R) -> zerompk::Result<Self> {
136 let len = reader.read_array_len()?;
137 if len == 0 {
138 return Err(zerompk::Error::ArrayLengthMismatch {
139 expected: 1,
140 actual: 0,
141 });
142 }
143 let tag = reader.read_u8()?;
144 match tag {
145 0 => Ok(Value::Null),
146 1 => Ok(Value::Bool(reader.read_boolean()?)),
147 2 => Ok(Value::Integer(reader.read_i64()?)),
148 3 => Ok(Value::Float(reader.read_f64()?)),
149 4 => Ok(Value::String(reader.read_string()?.into_owned())),
150 5 => Ok(Value::Bytes(reader.read_binary()?.into_owned())),
151 6 => Ok(Value::Array(Vec::<Value>::read(reader)?)),
152 7 => Ok(Value::Object(HashMap::<String, Value>::read(reader)?)),
153 8 => Ok(Value::Uuid(reader.read_string()?.into_owned())),
154 9 => Ok(Value::Ulid(reader.read_string()?.into_owned())),
155 10 => Ok(Value::DateTime(NdbDateTime::read(reader)?)),
156 11 => Ok(Value::Duration(NdbDuration::read(reader)?)),
157 12 => {
158 let cow = reader.read_binary()?;
159 if cow.len() != 16 {
160 return Err(zerompk::Error::BufferTooSmall);
161 }
162 let mut buf = [0u8; 16];
163 buf.copy_from_slice(&cow);
164 Ok(Value::Decimal(rust_decimal::Decimal::deserialize(buf)))
165 }
166 13 => Ok(Value::Geometry(Geometry::read(reader)?)),
167 14 => Ok(Value::Set(Vec::<Value>::read(reader)?)),
168 15 => Ok(Value::Regex(reader.read_string()?.into_owned())),
169 16 => {
170 let start = Option::<Box<Value>>::read(reader)?;
171 let end = Option::<Box<Value>>::read(reader)?;
172 let inclusive = reader.read_boolean()?;
173 Ok(Value::Range {
174 start,
175 end,
176 inclusive,
177 })
178 }
179 17 => {
180 let table = reader.read_string()?.into_owned();
181 let id = reader.read_string()?.into_owned();
182 Ok(Value::Record { table, id })
183 }
184 18 => Ok(Value::ArrayCell(ArrayCell::read(reader)?)),
185 19 => Ok(Value::NaiveDateTime(NdbDateTime::read(reader)?)),
186 20 => {
187 let cow = reader.read_binary()?;
188 if cow.len() % 4 != 0 {
189 return Err(zerompk::Error::BufferTooSmall);
190 }
191 let floats: Arc<[f32]> = cow
196 .chunks_exact(4)
197 .map(|chunk| {
198 let arr = [chunk[0], chunk[1], chunk[2], chunk[3]];
199 f32::from_ne_bytes(arr)
200 })
201 .collect();
202 Ok(Value::Vector(floats))
203 }
204 _ => Err(zerompk::Error::InvalidMarker(tag)),
205 }
206 }
207}