1use std::{collections::HashMap, str::from_utf8};
5
6use bigdecimal::BigDecimal;
7use num_bigint::BigInt;
8use reifydb_value::{
9 encoding::LeBytes,
10 params::Params,
11 value::{
12 Value,
13 blob::Blob,
14 date::Date,
15 datetime::DateTime,
16 decimal::Decimal,
17 dictionary::DictionaryEntryId,
18 duration::Duration,
19 identity::IdentityId,
20 int::Int,
21 ordered_f32::OrderedF32,
22 ordered_f64::OrderedF64,
23 time::Time,
24 uint::Uint,
25 uuid::{Uuid4, Uuid7},
26 },
27};
28
29use crate::{
30 error::{DecodeError, EncodeError},
31 reader::Reader,
32 tag::ValueKind,
33 typeinfo::{decode_value_type, encode_value_type},
34};
35
36pub fn encode_value(value: &Value) -> Result<Vec<u8>, EncodeError> {
37 let mut buf = Vec::new();
38 encode_value_into(value, &mut buf)?;
39 Ok(buf)
40}
41
42pub fn encode_value_into(value: &Value, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
43 buf.push(ValueKind::of_value(value).byte());
44 match value {
45 Value::None {
46 inner,
47 } => encode_value_type(inner, buf)?,
48 Value::Boolean(b) => buf.push(*b as u8),
49 Value::Float4(f) => buf.extend_from_slice(&f.to_le_bytes()),
50 Value::Float8(f) => buf.extend_from_slice(&f.to_le_bytes()),
51 Value::Int1(v) => buf.extend_from_slice(&v.to_le_bytes()),
52 Value::Int2(v) => buf.extend_from_slice(&v.to_le_bytes()),
53 Value::Int4(v) => buf.extend_from_slice(&v.to_le_bytes()),
54 Value::Int8(v) => buf.extend_from_slice(&v.to_le_bytes()),
55 Value::Int16(v) => buf.extend_from_slice(&v.to_le_bytes()),
56 Value::Utf8(s) => encode_len_prefixed(s.as_bytes(), buf),
57 Value::Uint1(v) => buf.extend_from_slice(&v.to_le_bytes()),
58 Value::Uint2(v) => buf.extend_from_slice(&v.to_le_bytes()),
59 Value::Uint4(v) => buf.extend_from_slice(&v.to_le_bytes()),
60 Value::Uint8(v) => buf.extend_from_slice(&v.to_le_bytes()),
61 Value::Uint16(v) => buf.extend_from_slice(&v.to_le_bytes()),
62 Value::Date(d) => buf.extend_from_slice(d.to_le_bytes().as_ref()),
63 Value::DateTime(dt) => buf.extend_from_slice(dt.to_le_bytes().as_ref()),
64 Value::Time(t) => buf.extend_from_slice(t.to_le_bytes().as_ref()),
65 Value::Duration(d) => buf.extend_from_slice(d.to_le_bytes().as_ref()),
66 Value::IdentityId(id) => buf.extend_from_slice(id.to_le_bytes().as_ref()),
67 Value::Uuid4(u) => buf.extend_from_slice(u.to_le_bytes().as_ref()),
68 Value::Uuid7(u) => buf.extend_from_slice(u.to_le_bytes().as_ref()),
69 Value::Blob(b) => encode_len_prefixed(b.as_bytes(), buf),
70 Value::Int(v) => encode_len_prefixed(&v.0.to_signed_bytes_le(), buf),
71 Value::Uint(v) => encode_len_prefixed(&v.0.to_signed_bytes_le(), buf),
72 Value::Decimal(v) => encode_len_prefixed(v.to_string().as_bytes(), buf),
73 Value::Any(inner) => encode_value_into(inner, buf)?,
74 Value::DictionaryId(id) => match id {
75 DictionaryEntryId::U1(v) => {
76 buf.push(1);
77 buf.extend_from_slice(&v.to_le_bytes());
78 }
79 DictionaryEntryId::U2(v) => {
80 buf.push(2);
81 buf.extend_from_slice(&v.to_le_bytes());
82 }
83 DictionaryEntryId::U4(v) => {
84 buf.push(4);
85 buf.extend_from_slice(&v.to_le_bytes());
86 }
87 DictionaryEntryId::U8(v) => {
88 buf.push(8);
89 buf.extend_from_slice(&v.to_le_bytes());
90 }
91 DictionaryEntryId::U16(v) => {
92 buf.push(16);
93 buf.extend_from_slice(&v.to_le_bytes());
94 }
95 },
96 Value::Type(ty) => encode_value_type(ty, buf)?,
97 Value::List(items) | Value::Tuple(items) => {
98 buf.extend_from_slice(&(items.len() as u32).to_le_bytes());
99 for item in items {
100 encode_value_into(item, buf)?;
101 }
102 }
103 Value::Record(fields) => {
104 buf.extend_from_slice(&(fields.len() as u32).to_le_bytes());
105 for (key, field_value) in fields {
106 encode_len_prefixed(key.as_bytes(), buf);
107 encode_value_into(field_value, buf)?;
108 }
109 }
110 }
111 Ok(())
112}
113
114fn encode_len_prefixed(bytes: &[u8], buf: &mut Vec<u8>) {
115 buf.extend_from_slice(&(bytes.len() as u32).to_le_bytes());
116 buf.extend_from_slice(bytes);
117}
118
119pub fn decode_value(bytes: &[u8]) -> Result<Value, DecodeError> {
120 let mut r = Reader::new(bytes);
121 let value = decode_value_from(&mut r)?;
122 if !r.is_empty() {
123 return Err(DecodeError::TrailingBytes(r.remaining()));
124 }
125 Ok(value)
126}
127
128pub fn decode_value_from(r: &mut Reader) -> Result<Value, DecodeError> {
129 let byte = r.u8()?;
130 let kind = ValueKind::from_byte(byte).ok_or(DecodeError::UnknownTypeCode(byte))?;
131 match kind {
132 ValueKind::None => Ok(Value::None {
133 inner: decode_value_type(r)?,
134 }),
135 ValueKind::Boolean => Ok(Value::Boolean(r.u8()? != 0)),
136 ValueKind::Float4 => OrderedF32::try_from(r.f32()?)
137 .map(Value::Float4)
138 .map_err(|e| DecodeError::InvalidData(format!("invalid float4: {e}"))),
139 ValueKind::Float8 => OrderedF64::try_from(r.f64()?)
140 .map(Value::Float8)
141 .map_err(|e| DecodeError::InvalidData(format!("invalid float8: {e}"))),
142 ValueKind::Int1 => Ok(Value::Int1(r.i8()?)),
143 ValueKind::Int2 => Ok(Value::Int2(r.i16()?)),
144 ValueKind::Int4 => Ok(Value::Int4(r.i32()?)),
145 ValueKind::Int8 => Ok(Value::Int8(r.i64()?)),
146 ValueKind::Int16 => Ok(Value::Int16(r.i128()?)),
147 ValueKind::Utf8 => Ok(Value::Utf8(decode_len_prefixed_str(r)?.to_string())),
148 ValueKind::Uint1 => Ok(Value::Uint1(r.u8()?)),
149 ValueKind::Uint2 => Ok(Value::Uint2(r.u16()?)),
150 ValueKind::Uint4 => Ok(Value::Uint4(r.u32()?)),
151 ValueKind::Uint8 => Ok(Value::Uint8(r.u64()?)),
152 ValueKind::Uint16 => Ok(Value::Uint16(r.u128()?)),
153 ValueKind::Date => {
154 let days = r.i32()?;
155 Date::from_days_since_epoch(days)
156 .map(Value::Date)
157 .ok_or_else(|| DecodeError::InvalidData(format!("invalid date: {days}")))
158 }
159 ValueKind::DateTime => Ok(Value::DateTime(DateTime::read_le(r.take(DateTime::ENCODED_SIZE)?))),
160 ValueKind::Time => {
161 let nanos = r.u64()?;
162 Time::from_nanos_since_midnight(nanos)
163 .map(Value::Time)
164 .ok_or_else(|| DecodeError::InvalidData(format!("invalid time: {nanos}")))
165 }
166 ValueKind::Duration => {
167 let months = r.i32()?;
168 let days = r.i32()?;
169 let nanos = r.i64()?;
170 Duration::new(months, days, nanos)
171 .map(Value::Duration)
172 .map_err(|e| DecodeError::InvalidData(format!("invalid duration: {e}")))
173 }
174 ValueKind::IdentityId => Ok(Value::IdentityId(IdentityId::read_le(r.take(IdentityId::ENCODED_SIZE)?))),
175 ValueKind::Uuid4 => Ok(Value::Uuid4(Uuid4::read_le(r.take(Uuid4::ENCODED_SIZE)?))),
176 ValueKind::Uuid7 => Ok(Value::Uuid7(Uuid7::read_le(r.take(Uuid7::ENCODED_SIZE)?))),
177 ValueKind::Blob => Ok(Value::Blob(Blob::new(decode_len_prefixed_bytes(r)?.to_vec()))),
178 ValueKind::Int => Ok(Value::Int(Int(BigInt::from_signed_bytes_le(decode_len_prefixed_bytes(r)?)))),
179 ValueKind::Uint => Ok(Value::Uint(Uint(BigInt::from_signed_bytes_le(decode_len_prefixed_bytes(r)?)))),
180 ValueKind::Decimal => {
181 let s = decode_len_prefixed_str(r)?;
182 let dec: BigDecimal =
183 s.parse().map_err(|e| DecodeError::InvalidData(format!("invalid decimal: {e}")))?;
184 Ok(Value::Decimal(Decimal::new(dec)))
185 }
186 ValueKind::Any => Ok(Value::Any(Box::new(decode_value_from(r)?))),
187 ValueKind::DictionaryId => {
188 let width = r.u8()?;
189 let id = match width {
190 1 => DictionaryEntryId::U1(r.u8()?),
191 2 => DictionaryEntryId::U2(r.u16()?),
192 4 => DictionaryEntryId::U4(r.u32()?),
193 8 => DictionaryEntryId::U8(r.u64()?),
194 16 => DictionaryEntryId::U16(r.u128()?),
195 other => {
196 return Err(DecodeError::InvalidData(format!(
197 "invalid dictionary id width: {other}"
198 )));
199 }
200 };
201 Ok(Value::DictionaryId(id))
202 }
203 ValueKind::Type => Ok(Value::Type(decode_value_type(r)?)),
204 ValueKind::List => Ok(Value::List(decode_value_sequence(r)?)),
205 ValueKind::Tuple => Ok(Value::Tuple(decode_value_sequence(r)?)),
206 ValueKind::Record => {
207 let count = r.u32()?;
208 let mut fields = Vec::with_capacity((count as usize).min(4096));
209 for _ in 0..count {
210 let key = decode_len_prefixed_str(r)?.to_string();
211 fields.push((key, decode_value_from(r)?));
212 }
213 Ok(Value::Record(fields))
214 }
215 }
216}
217
218fn decode_value_sequence(r: &mut Reader) -> Result<Vec<Value>, DecodeError> {
219 let count = r.u32()?;
220 let mut items = Vec::with_capacity((count as usize).min(4096));
221 for _ in 0..count {
222 items.push(decode_value_from(r)?);
223 }
224 Ok(items)
225}
226
227fn decode_len_prefixed_bytes<'a>(r: &mut Reader<'a>) -> Result<&'a [u8], DecodeError> {
228 let len = r.u32()? as usize;
229 r.take(len)
230}
231
232fn decode_len_prefixed_str<'a>(r: &mut Reader<'a>) -> Result<&'a str, DecodeError> {
233 from_utf8(decode_len_prefixed_bytes(r)?).map_err(|e| DecodeError::InvalidData(format!("invalid UTF-8: {e}")))
234}
235
236pub fn encode_params(params: &Params) -> Result<Vec<u8>, EncodeError> {
237 let mut buf = Vec::new();
238 match params {
239 Params::None => buf.push(0),
240 Params::Positional(values) => {
241 buf.push(1);
242 buf.extend_from_slice(&(values.len() as u32).to_le_bytes());
243 for value in values.iter() {
244 encode_value_into(value, &mut buf)?;
245 }
246 }
247 Params::Named(map) => {
248 buf.push(2);
249 buf.extend_from_slice(&(map.len() as u32).to_le_bytes());
250 for (key, value) in map.iter() {
251 encode_len_prefixed(key.as_bytes(), &mut buf);
252 encode_value_into(value, &mut buf)?;
253 }
254 }
255 }
256 Ok(buf)
257}
258
259pub fn decode_params(bytes: &[u8]) -> Result<Params, DecodeError> {
260 let mut r = Reader::new(bytes);
261 let discriminant = r.u8()?;
262 let params = match discriminant {
263 0 => Params::None,
264 1 => {
265 let count = r.u32()?;
266 let mut values = Vec::with_capacity((count as usize).min(4096));
267 for _ in 0..count {
268 values.push(decode_value_from(&mut r)?);
269 }
270 Params::Positional(values.into())
271 }
272 2 => {
273 let count = r.u32()?;
274 let mut map = HashMap::with_capacity((count as usize).min(4096));
275 for _ in 0..count {
276 let key = decode_len_prefixed_str(&mut r)?.to_string();
277 map.insert(key, decode_value_from(&mut r)?);
278 }
279 Params::Named(map.into())
280 }
281 other => {
282 return Err(DecodeError::InvalidData(format!("invalid params discriminant: {other}")));
283 }
284 };
285 if !r.is_empty() {
286 return Err(DecodeError::TrailingBytes(r.remaining()));
287 }
288 Ok(params)
289}