reifydb_codec/
typeinfo.rs1use std::str::from_utf8;
5
6use reifydb_value::value::{digest::Digest, 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 unscaled::{decode_params, family_type},
13};
14
15pub fn encode_value_type(ty: &ValueType, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
16 let (base, depth) = peel_options(ty);
17 if depth > MAX_OPTION_DEPTH as u32 {
18 if depth > u8::MAX as u32 {
19 return Err(EncodeError::OptionDepthTooDeep {
20 depth,
21 max: u8::MAX,
22 });
23 }
24 buf.push(EXTENDED_TYPE_TAG);
25 buf.push(depth as u8);
26 encode_base(base, 0, buf)
27 } else {
28 encode_base(base, depth as u8, buf)
29 }
30}
31
32fn encode_base(base: &ValueType, depth: u8, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
33 let tag = TypeTag::new(ValueKind::of_type(base), depth)?;
34 buf.push(tag.byte());
35 match base {
36 ValueType::List(element) => encode_value_type(element, buf)?,
37 ValueType::Record(fields) => {
38 buf.extend_from_slice(&(fields.len() as u16).to_le_bytes());
39 for (name, field_ty) in fields {
40 let name_bytes = name.as_bytes();
41 buf.extend_from_slice(&(name_bytes.len() as u16).to_le_bytes());
42 buf.extend_from_slice(name_bytes);
43 encode_value_type(field_ty, buf)?;
44 }
45 }
46 ValueType::Tuple(elements) => {
47 buf.extend_from_slice(&(elements.len() as u16).to_le_bytes());
48 for element in elements {
49 encode_value_type(element, buf)?;
50 }
51 }
52 ValueType::Digest {
53 inner,
54 accuracy,
55 } => encode_digest_params(inner, *accuracy, buf)?,
56 ValueType::Decimal {
57 precision,
58 scale,
59 } => {
60 buf.push(precision.value());
61 buf.push(scale.value());
62 }
63 _ => {}
64 }
65 Ok(())
66}
67
68pub fn encode_digest_params(inner: &ValueType, accuracy: u32, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
69 Digest::new(inner.clone(), accuracy).map_err(|error| EncodeError::UnsupportedType(error.to_string()))?;
70 buf.push(ValueKind::of_type(inner).byte());
71 buf.extend_from_slice(&accuracy.to_le_bytes());
72 Ok(())
73}
74
75pub fn decode_digest_params(r: &mut Reader) -> Result<(ValueType, u32), DecodeError> {
76 let inner = TypeTag::from_byte(r.u8()?)?.to_type()?;
77 let accuracy = r.u32()?;
78 Digest::new(inner.clone(), accuracy)
79 .map_err(|error| DecodeError::InvalidData(format!("invalid digest type: {error}")))?;
80 Ok((inner, accuracy))
81}
82
83pub fn decode_value_type(r: &mut Reader) -> Result<ValueType, DecodeError> {
84 let first = r.u8()?;
85 if first == EXTENDED_TYPE_TAG {
86 let depth = r.u8()?;
87 let base = decode_value_type(r)?;
88 return Ok((0..depth).fold(base, |ty, _| ValueType::Option(Box::new(ty))));
89 }
90 let tag = TypeTag::from_byte(first)?;
91 let kind = tag.kind().ok_or(DecodeError::UnknownTypeCode(first))?;
92 let base = match kind {
93 ValueKind::List => ValueType::List(Box::new(decode_value_type(r)?)),
94 ValueKind::Record => {
95 let count = r.u16()?;
96 let mut fields = Vec::with_capacity(count as usize);
97 for _ in 0..count {
98 let name_len = r.u16()? as usize;
99 let name = from_utf8(r.take(name_len)?)
100 .map_err(|e| {
101 DecodeError::InvalidData(format!(
102 "invalid UTF-8 in record field name: {e}"
103 ))
104 })?
105 .to_string();
106 fields.push((name, decode_value_type(r)?));
107 }
108 ValueType::Record(fields)
109 }
110 ValueKind::Tuple => {
111 let count = r.u16()?;
112 let mut elements = Vec::with_capacity(count as usize);
113 for _ in 0..count {
114 elements.push(decode_value_type(r)?);
115 }
116 ValueType::Tuple(elements)
117 }
118 ValueKind::Digest => {
119 let (inner, accuracy) = decode_digest_params(r)?;
120 ValueType::Digest {
121 inner: Box::new(inner),
122 accuracy,
123 }
124 }
125 ValueKind::Decimal => {
126 let precision = r.u8()?;
127 let (precision, scale) = decode_params(precision, r.u8()?)?;
128 family_type(kind, precision, scale)?
129 }
130 _ => return tag.to_type(),
131 };
132 Ok((0..tag.depth()).fold(base, |ty, _| ValueType::Option(Box::new(ty))))
133}