1use crate::data_type::Type;
2use crate::storage::Storage;
3use crate::subtype::SubType;
4use crate::{data_type, utils, Error, List, Map, Object};
5use byteorder::{BigEndian, ByteOrder};
6
7use crate::error::Result;
8use crate::raw_container::{KeyType, RawContainer};
9use crate::size::Size;
10
11#[derive(Debug, PartialEq)]
13pub enum Value<'a> {
14 Null,
16
17 True,
19
20 False,
22
23 UInt8(u8),
25
26 Int8(i8),
28
29 UInt16(u16),
31
32 Int16(i16),
34
35 UInt32(u32),
37
38 Int32(i32),
40
41 Float(f32),
43
44 UInt64(u64),
46
47 Int64(i64),
49
50 Double(f64),
52
53 Text(&'a str),
55
56 DateTime(&'a str),
58
59 Date(&'a str),
61
62 Time(&'a str),
64
65 DecimalStr(&'a str),
67
68 Blob(&'a [u8]),
70
71 List(List<'a>),
73
74 Map(Map<'a>),
76
77 Object(Object<'a>),
80
81 Empty(SubType),
83
84 Byte(SubType, u8),
86
87 Word(SubType, u16),
89
90 DWord(SubType, u32),
92
93 QWord(SubType, u64),
95
96 UserText(SubType, &'a str),
98
99 UserBlob(SubType, &'a [u8]),
101}
102
103impl<'a> Value<'a> {
104 pub(crate) fn data_size(&self) -> Option<usize> {
110 match self {
111 Value::Text(t)
112 | Value::DateTime(t)
113 | Value::Date(t)
114 | Value::Time(t)
115 | Value::DecimalStr(t)
116 | Value::UserText(_, t) => Some(t.len() + 1),
117
118 Value::Blob(b) | Value::UserBlob(_, b) => Some(b.len()),
119
120 Value::List(_) | Value::Map(_) | Value::Object(_) => unreachable!(),
121
122 _ => None,
123 }
124 }
125
126 pub(crate) fn get_type(&self) -> Type {
128 match self {
129 Value::Null => data_type::NULL,
130 Value::True => data_type::TRUE,
131 Value::False => data_type::FALSE,
132 Value::UInt8(_) => data_type::UINT8,
133 Value::Int8(_) => data_type::INT8,
134 Value::UInt16(_) => data_type::UINT16,
135 Value::Int16(_) => data_type::INT16,
136 Value::UInt32(_) => data_type::UINT32,
137 Value::Int32(_) => data_type::INT32,
138 Value::Float(_) => data_type::FLOAT,
139 Value::UInt64(_) => data_type::UINT64,
140 Value::Int64(_) => data_type::INT64,
141 Value::Double(_) => data_type::DOUBLE,
142 Value::Text(_) => data_type::TEXT,
143 Value::DateTime(_) => data_type::DATE_TIME,
144 Value::Date(_) => data_type::DATE,
145 Value::Time(_) => data_type::TIME,
146 Value::DecimalStr(_) => data_type::DECIMAL_STR,
147 Value::Blob(_) => data_type::BLOB,
148 Value::List(_) => data_type::LIST,
149 Value::Map(_) => data_type::MAP,
150 Value::Object(_) => data_type::OBJECT,
151 Value::Empty(sub) => Type {
152 storage: Storage::NoBytes,
153 subtype: *sub,
154 },
155 Value::Byte(sub, _) => Type {
156 storage: Storage::Byte,
157 subtype: *sub,
158 },
159 Value::Word(sub, _) => Type {
160 storage: Storage::Word,
161 subtype: *sub,
162 },
163 Value::DWord(sub, _) => Type {
164 storage: Storage::DWord,
165 subtype: *sub,
166 },
167 Value::QWord(sub, _) => Type {
168 storage: Storage::QWord,
169 subtype: *sub,
170 },
171 Value::UserText(sub, _) => Type {
172 storage: Storage::String,
173 subtype: *sub,
174 },
175 Value::UserBlob(sub, _) => Type {
176 storage: Storage::Blob,
177 subtype: *sub,
178 },
179 }
180 }
181
182 pub(crate) fn total_size(&self) -> usize {
184 match self {
186 Value::List(list) => return list.as_bytes().len(),
187 Value::Map(map) => return map.as_bytes().len(),
188 Value::Object(obj) => return obj.as_bytes().len(),
189 _ => {}
190 }
191
192 let value_type = self.get_type();
193
194 let type_size = value_type.size();
195
196 let fixed_size = value_type.storage.fixed_size();
197 let data_size = self.data_size();
198
199 if let Some(data_size) = fixed_size {
200 type_size + data_size
201 } else if let Some(data_size) = data_size {
202 type_size + Size::new(data_size).unwrap().size() + data_size
203 } else {
204 unreachable!()
206 }
207 }
208
209 pub(crate) fn write<'b>(&self, buf: &'b mut [u8]) -> Result<(&'b mut [u8], usize)> {
212 let total_size = self.total_size();
213
214 if buf.len() < total_size {
215 return Err(Error::SmallBuffer(total_size - buf.len()));
216 }
217
218 match self {
219 Value::List(list) => {
220 buf[..total_size].copy_from_slice(list.as_bytes());
221 return Ok((&mut buf[total_size..], total_size));
222 }
223 Value::Map(map) => {
224 buf[..total_size].copy_from_slice(map.as_bytes());
225 return Ok((&mut buf[total_size..], total_size));
226 }
227 Value::Object(obj) => {
228 buf[..total_size].copy_from_slice(obj.as_bytes());
229 return Ok((&mut buf[total_size..], total_size));
230 }
231 _ => {}
232 }
233
234 let value_type = self.get_type();
235
236 let fixed_size = value_type.storage.fixed_size();
237 let data_size = self.data_size();
238
239 let mut buf = value_type.write(buf);
241
242 if let Some(mut data_size) = data_size {
244 if value_type.storage == Storage::String {
245 data_size -= 1;
247 }
248 buf = Size::new(data_size).unwrap().write(buf).unwrap();
249 }
250
251 match self {
253 Value::Null | Value::True | Value::False | Value::Empty(_) => {}
254
255 Value::UInt8(val) | Value::Byte(_, val) => buf[0] = *val,
256 Value::Int8(val) => buf[0] = *val as u8,
257 Value::UInt16(val) | Value::Word(_, val) => BigEndian::write_u16(buf, *val),
258 Value::Int16(val) => BigEndian::write_i16(buf, *val),
259 Value::UInt32(val) | Value::DWord(_, val) => BigEndian::write_u32(buf, *val),
260 Value::Int32(val) => BigEndian::write_i32(buf, *val),
261 Value::Float(val) => BigEndian::write_f32(buf, *val),
262 Value::UInt64(val) | Value::QWord(_, val) => BigEndian::write_u64(buf, *val),
263 Value::Int64(val) => BigEndian::write_i64(buf, *val),
264 Value::Double(val) => BigEndian::write_f64(buf, *val),
265
266 Value::Text(val)
267 | Value::DateTime(val)
268 | Value::Date(val)
269 | Value::Time(val)
270 | Value::DecimalStr(val)
271 | Value::UserText(_, val) => buf[..val.len()].copy_from_slice(val.as_bytes()),
272
273 Value::Blob(val) | Value::UserBlob(_, val) => buf[..val.len()].copy_from_slice(val),
274
275 _ => unreachable!(),
276 }
277
278 let buf = &mut buf[data_size.or(fixed_size).unwrap()..];
280
281 Ok((buf, total_size))
282 }
283}
284
285impl<'a> TryFrom<&'a [u8]> for Value<'a> {
286 type Error = Error;
287
288 fn try_from(bytes: &'a [u8]) -> Result<Self> {
289 let data_type: Type = bytes.try_into()?;
290 let value = &bytes[data_type.size()..];
291
292 match data_type {
293 data_type::NULL => return Ok(Value::Null),
294 data_type::TRUE => return Ok(Value::True),
295 data_type::FALSE => return Ok(Value::False),
296 data_type::UINT8 => return Ok(Value::UInt8(utils::read_u8(value)?)),
297 data_type::INT8 => return Ok(Value::Int8(utils::read_i8(value)?)),
298 data_type::UINT16 => return Ok(Value::UInt16(utils::read_u16(value)?)),
299 data_type::INT16 => return Ok(Value::Int16(utils::read_i16(value)?)),
300 data_type::UINT32 => return Ok(Value::UInt32(utils::read_u32(value)?)),
301 data_type::INT32 => return Ok(Value::Int32(utils::read_i32(value)?)),
302 data_type::FLOAT => return Ok(Value::Float(utils::read_f32(value)?)),
303 data_type::UINT64 => return Ok(Value::UInt64(utils::read_u64(value)?)),
304 data_type::INT64 => return Ok(Value::Int64(utils::read_i64(value)?)),
305 data_type::DOUBLE => return Ok(Value::Double(utils::read_f64(value)?)),
306 data_type::TEXT => return Ok(Value::Text(utils::read_text(value)?)),
307 data_type::DATE_TIME => return Ok(Value::DateTime(utils::read_text(value)?)),
308 data_type::DATE => return Ok(Value::Date(utils::read_text(value)?)),
309 data_type::TIME => return Ok(Value::Time(utils::read_text(value)?)),
310 data_type::DECIMAL_STR => return Ok(Value::DecimalStr(utils::read_text(value)?)),
311 data_type::BLOB => return Ok(Value::Blob(utils::read_blob(value)?)),
312 Type {
313 storage: Storage::NoBytes,
314 subtype,
315 } => return Ok(Value::Empty(subtype)),
316 Type {
317 storage: Storage::Byte,
318 subtype,
319 } => return Ok(Value::Byte(subtype, utils::read_u8(value)?)),
320 Type {
321 storage: Storage::Word,
322 subtype,
323 } => return Ok(Value::Word(subtype, utils::read_u16(value)?)),
324 Type {
325 storage: Storage::DWord,
326 subtype,
327 } => return Ok(Value::DWord(subtype, utils::read_u32(value)?)),
328 Type {
329 storage: Storage::QWord,
330 subtype,
331 } => return Ok(Value::QWord(subtype, utils::read_u64(value)?)),
332 Type {
333 storage: Storage::String,
334 subtype,
335 } => return Ok(Value::UserText(subtype, utils::read_text(value)?)),
336 Type {
337 storage: Storage::Blob,
338 subtype,
339 } => return Ok(Value::UserBlob(subtype, utils::read_blob(value)?)),
340 Type {
342 storage: Storage::Container,
343 subtype: _,
344 } => {}
345 }
346 match data_type {
349 data_type::LIST => Ok(Value::List(List {
350 inner: RawContainer::from_bytes(bytes, KeyType::Empty)?,
351 })),
352 data_type::MAP => Ok(Value::Map(Map {
353 inner: RawContainer::from_bytes(bytes, KeyType::Num)?,
354 })),
355 data_type::OBJECT => Ok(Value::Object(Object {
356 inner: RawContainer::from_bytes(bytes, KeyType::Str)?,
357 })),
358 Type {
359 storage: Storage::Container,
360 subtype: _,
361 } => Err(Error::Malformed),
362 _ => unreachable!(),
363 }
364 }
365}
366
367impl<'a> TryFrom<Value<'a>> for List<'a> {
368 type Error = Value<'a>;
369
370 fn try_from(value: Value<'a>) -> core::result::Result<Self, Self::Error> {
371 if let Value::List(list) = value {
372 Ok(list)
373 } else {
374 Err(value)
375 }
376 }
377}
378
379impl<'a> TryFrom<Value<'a>> for Map<'a> {
380 type Error = Value<'a>;
381
382 fn try_from(value: Value<'a>) -> core::result::Result<Self, Self::Error> {
383 if let Value::Map(map) = value {
384 Ok(map)
385 } else {
386 Err(value)
387 }
388 }
389}
390
391impl<'a> TryFrom<Value<'a>> for Object<'a> {
392 type Error = Value<'a>;
393
394 fn try_from(value: Value<'a>) -> core::result::Result<Self, Self::Error> {
395 if let Value::Object(obj) = value {
396 Ok(obj)
397 } else {
398 Err(value)
399 }
400 }
401}
402
403pub trait AsValue<'a> {
407 fn to_value(self) -> Value<'a>;
408}
409
410impl<'a> AsValue<'a> for Value<'a> {
411 fn to_value(self) -> Value<'a> {
412 self
413 }
414}