reifydb_codec/extern_c/
cells.rs1use arrow_buffer::i256;
5use reifydb_value::value::{
6 Value,
7 constraint::{precision::Precision, scale::Scale},
8 decimal::Decimal,
9 dictionary::DictionaryEntryId,
10 duration::Duration,
11};
12
13use crate::{
14 error::{DecodeError, EncodeError},
15 reader::Reader,
16 tag::ValueKind,
17 unscaled::{NARROW, WIDE, decimal_unscaled, extend_le, read_le, width},
18 value::{decode_value, encode_value_into},
19};
20
21pub fn encode_decimal_cell(
22 value: &Decimal,
23 precision: Precision,
24 scale: Scale,
25 buf: &mut Vec<u8>,
26) -> Result<(), EncodeError> {
27 let unscaled = decimal_unscaled(value, precision, scale).ok_or_else(|| {
28 EncodeError::UnsupportedType(format!(
29 "decimal {value} does not fit precision {} and scale {}",
30 precision.value(),
31 scale.value()
32 ))
33 })?;
34 extend_le(unscaled, width(precision), buf);
35 Ok(())
36}
37
38pub fn decode_decimal_cell(bytes: &[u8], scale: Scale) -> Result<Decimal, DecodeError> {
39 let unscaled = read_cell(ValueKind::Decimal, bytes)?;
40 Decimal::from_parts(unscaled, scale.value()).ok_or_else(|| {
41 DecodeError::InvalidData(format!(
42 "decimal cell {unscaled} at scale {} exceeds 76 digits",
43 scale.value()
44 ))
45 })
46}
47
48fn read_cell(kind: ValueKind, bytes: &[u8]) -> Result<i256, DecodeError> {
49 match bytes.len() {
50 NARROW | WIDE => Ok(read_le(bytes)),
51 other => Err(DecodeError::InvalidData(format!("{kind:?} cell is {other} bytes, expected 16 or 32"))),
52 }
53}
54
55pub fn encode_any_cell(value: &Value, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
56 encode_value_into(value, buf)
57}
58
59pub fn decode_any_cell(bytes: &[u8]) -> Result<Value, DecodeError> {
60 decode_value(bytes)
61}
62
63pub fn encode_dictionary_id_cell(id: &DictionaryEntryId, buf: &mut Vec<u8>) {
64 match id {
65 DictionaryEntryId::U1(v) => {
66 buf.push(1);
67 buf.extend_from_slice(&v.to_le_bytes());
68 }
69 DictionaryEntryId::U2(v) => {
70 buf.push(2);
71 buf.extend_from_slice(&v.to_le_bytes());
72 }
73 DictionaryEntryId::U4(v) => {
74 buf.push(4);
75 buf.extend_from_slice(&v.to_le_bytes());
76 }
77 DictionaryEntryId::U8(v) => {
78 buf.push(8);
79 buf.extend_from_slice(&v.to_le_bytes());
80 }
81 DictionaryEntryId::U16(v) => {
82 buf.push(16);
83 buf.extend_from_slice(&v.to_le_bytes());
84 }
85 }
86}
87
88pub fn decode_dictionary_id_cell(bytes: &[u8]) -> Result<DictionaryEntryId, DecodeError> {
89 let mut r = Reader::new(bytes);
90 let width = r.u8()?;
91 let id = match width {
92 1 => DictionaryEntryId::U1(r.u8()?),
93 2 => DictionaryEntryId::U2(r.u16()?),
94 4 => DictionaryEntryId::U4(r.u32()?),
95 8 => DictionaryEntryId::U8(r.u64()?),
96 16 => DictionaryEntryId::U16(r.u128()?),
97 other => {
98 return Err(DecodeError::InvalidData(format!("invalid dictionary id width: {other}")));
99 }
100 };
101 if !r.is_empty() {
102 return Err(DecodeError::TrailingBytes(r.remaining()));
103 }
104 Ok(id)
105}
106
107pub fn encode_duration_cell(value: &Duration, buf: &mut Vec<u8>) {
108 buf.extend_from_slice(&value.get_months().to_le_bytes());
109 buf.extend_from_slice(&value.get_days().to_le_bytes());
110 buf.extend_from_slice(&value.get_nanos().to_le_bytes());
111}
112
113pub fn decode_duration_cell(bytes: &[u8]) -> Result<Duration, DecodeError> {
114 let mut r = Reader::new(bytes);
115 let months = r.i32()?;
116 let days = r.i32()?;
117 let nanos = r.i64()?;
118 if !r.is_empty() {
119 return Err(DecodeError::TrailingBytes(r.remaining()));
120 }
121 Duration::new(months, days, nanos).map_err(|e| DecodeError::InvalidData(format!("invalid duration: {e}")))
122}