reifydb_codec/
typeinfo.rs1use std::str::from_utf8;
5
6use reifydb_value::value::value_type::ValueType;
7
8use crate::{
9 error::{DecodeError, EncodeError},
10 reader::Reader,
11 tag::{EXTENDED_TYPE_TAG, MAX_OPTION_DEPTH, TypeTag, ValueKind, peel_options},
12};
13
14pub fn encode_value_type(ty: &ValueType, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
15 let (base, depth) = peel_options(ty);
16 if depth > MAX_OPTION_DEPTH as u32 {
17 if depth > u8::MAX as u32 {
18 return Err(EncodeError::OptionDepthTooDeep {
19 depth,
20 max: u8::MAX,
21 });
22 }
23 buf.push(EXTENDED_TYPE_TAG);
24 buf.push(depth as u8);
25 encode_base(base, 0, buf)
26 } else {
27 encode_base(base, depth as u8, buf)
28 }
29}
30
31fn encode_base(base: &ValueType, depth: u8, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
32 let tag = TypeTag::new(ValueKind::of_type(base), depth)?;
33 buf.push(tag.byte());
34 match base {
35 ValueType::List(element) => encode_value_type(element, buf)?,
36 ValueType::Record(fields) => {
37 buf.extend_from_slice(&(fields.len() as u16).to_le_bytes());
38 for (name, field_ty) in fields {
39 let name_bytes = name.as_bytes();
40 buf.extend_from_slice(&(name_bytes.len() as u16).to_le_bytes());
41 buf.extend_from_slice(name_bytes);
42 encode_value_type(field_ty, buf)?;
43 }
44 }
45 ValueType::Tuple(elements) => {
46 buf.extend_from_slice(&(elements.len() as u16).to_le_bytes());
47 for element in elements {
48 encode_value_type(element, buf)?;
49 }
50 }
51 _ => {}
52 }
53 Ok(())
54}
55
56pub fn decode_value_type(r: &mut Reader) -> Result<ValueType, DecodeError> {
57 let first = r.u8()?;
58 if first == EXTENDED_TYPE_TAG {
59 let depth = r.u8()?;
60 let base = decode_value_type(r)?;
61 return Ok((0..depth).fold(base, |ty, _| ValueType::Option(Box::new(ty))));
62 }
63 let tag = TypeTag::from_byte(first)?;
64 let kind = tag.kind().ok_or(DecodeError::UnknownTypeCode(first))?;
65 let base = match kind {
66 ValueKind::List => ValueType::List(Box::new(decode_value_type(r)?)),
67 ValueKind::Record => {
68 let count = r.u16()?;
69 let mut fields = Vec::with_capacity(count as usize);
70 for _ in 0..count {
71 let name_len = r.u16()? as usize;
72 let name = from_utf8(r.take(name_len)?)
73 .map_err(|e| {
74 DecodeError::InvalidData(format!(
75 "invalid UTF-8 in record field name: {e}"
76 ))
77 })?
78 .to_string();
79 fields.push((name, decode_value_type(r)?));
80 }
81 ValueType::Record(fields)
82 }
83 ValueKind::Tuple => {
84 let count = r.u16()?;
85 let mut elements = Vec::with_capacity(count as usize);
86 for _ in 0..count {
87 elements.push(decode_value_type(r)?);
88 }
89 ValueType::Tuple(elements)
90 }
91 _ => return tag.to_type(),
92 };
93 Ok((0..tag.depth()).fold(base, |ty, _| ValueType::Option(Box::new(ty))))
94}