1use arrow_buffer::i256;
5use reifydb_value::{
6 Result,
7 error::{Error, TypeError},
8 value::{
9 Value,
10 blob::Blob,
11 constraint::precision::Precision,
12 date::Date,
13 datetime::DateTime,
14 decimal::Decimal,
15 dictionary::DictionaryEntryId,
16 duration::Duration,
17 identity::IdentityId,
18 ordered_f32::OrderedF32,
19 ordered_f64::OrderedF64,
20 time::Time,
21 uuid::{Uuid4, Uuid7},
22 },
23};
24use uuid::Uuid;
25
26use super::{
27 CONTAINER_END, decode_bool, decode_f32, decode_f64, decode_fixed, decode_i8, decode_i16, decode_i32,
28 decode_i64, decode_i128, decode_i256, decode_u8, decode_u16, decode_u32, decode_u64, decode_u128,
29 decode_u128_varint,
30};
31use crate::{
32 error::DecodeError,
33 tag::{TypeTag, ValueKind},
34 unscaled::{NARROW, check_unscaled, decode_params, width},
35};
36
37pub struct KeyDeserializer<'a> {
38 buffer: &'a [u8],
39 position: usize,
40}
41
42impl<'a> KeyDeserializer<'a> {
43 pub fn from_bytes(buffer: &'a [u8]) -> Self {
44 Self {
45 buffer,
46 position: 0,
47 }
48 }
49
50 pub fn remaining(&self) -> usize {
51 self.buffer.len().saturating_sub(self.position)
52 }
53
54 pub fn is_empty(&self) -> bool {
55 self.remaining() == 0
56 }
57
58 pub fn position(&self) -> usize {
59 self.position
60 }
61
62 pub fn remaining_bytes(&self) -> &'a [u8] {
63 &self.buffer[self.position..]
64 }
65
66 fn read_exact(&mut self, count: usize) -> Result<&'a [u8]> {
67 if self.remaining() < count {
68 return Err(Error::from(TypeError::SerdeKeycode {
69 message: format!(
70 "unexpected end of key at position {}: need {} bytes, have {}",
71 self.position,
72 count,
73 self.remaining()
74 ),
75 }));
76 }
77 let start = self.position;
78 self.position += count;
79 Ok(&self.buffer[start..self.position])
80 }
81
82 pub fn read_bool(&mut self) -> Result<bool> {
83 let bytes = self.read_exact(1)?;
84 decode_bool(bytes[0])
85 }
86
87 pub fn read_f32(&mut self) -> Result<f32> {
88 let bytes = self.read_exact(4)?;
89 Ok(decode_f32(bytes.try_into()?))
90 }
91
92 pub fn read_f64(&mut self) -> Result<f64> {
93 let bytes = self.read_exact(8)?;
94 Ok(decode_f64(bytes.try_into()?))
95 }
96
97 pub fn read_i8(&mut self) -> Result<i8> {
98 let bytes = self.read_exact(1)?;
99 Ok(decode_i8(bytes.try_into()?))
100 }
101
102 pub fn read_i16(&mut self) -> Result<i16> {
103 let bytes = self.read_exact(2)?;
104 Ok(decode_i16(bytes.try_into()?))
105 }
106
107 pub fn read_i32(&mut self) -> Result<i32> {
108 let bytes = self.read_exact(4)?;
109 Ok(decode_i32(bytes.try_into()?))
110 }
111
112 pub fn read_i64(&mut self) -> Result<i64> {
113 let bytes = self.read_exact(8)?;
114 Ok(decode_i64(bytes.try_into()?))
115 }
116
117 pub fn read_i128(&mut self) -> Result<i128> {
118 let bytes = self.read_exact(16)?;
119 Ok(decode_i128(bytes.try_into()?))
120 }
121
122 pub fn read_u8(&mut self) -> Result<u8> {
123 let bytes = self.read_exact(1)?;
124 Ok(decode_u8(bytes[0]))
125 }
126
127 pub fn read_u16(&mut self) -> Result<u16> {
128 let bytes = self.read_exact(2)?;
129 Ok(decode_u16(bytes.try_into()?))
130 }
131
132 pub fn read_u32(&mut self) -> Result<u32> {
133 let bytes = self.read_exact(4)?;
134 Ok(decode_u32(bytes.try_into()?))
135 }
136
137 pub fn read_u64(&mut self) -> Result<u64> {
138 let bytes = self.read_exact(8)?;
139 Ok(decode_u64(bytes.try_into()?))
140 }
141
142 pub fn read_u128(&mut self) -> Result<u128> {
143 let bytes = self.read_exact(16)?;
144 Ok(decode_u128(bytes.try_into()?))
145 }
146
147 pub fn read_fixed<const N: usize>(&mut self) -> Result<[u8; N]> {
148 let bytes = self.read_exact(N)?;
149 Ok(decode_fixed(bytes.try_into()?))
150 }
151
152 pub fn read_u128_varint(&mut self) -> Result<u128> {
153 let mut slice = &self.buffer[self.position..];
154 let u = decode_u128_varint(&mut slice)?;
155 self.position = self.buffer.len() - slice.len();
156 Ok(u)
157 }
158
159 pub fn read_bytes(&mut self) -> Result<Vec<u8>> {
160 let mut result = Vec::new();
161 loop {
162 if self.remaining() < 1 {
163 return Err(Error::from(TypeError::SerdeKeycode {
164 message: format!(
165 "unexpected end of key at position {}: bytes not terminated",
166 self.position
167 ),
168 }));
169 }
170 let byte = self.buffer[self.position];
171 self.position += 1;
172
173 if byte == 0xff {
174 if self.remaining() < 1 {
175 return Err(Error::from(TypeError::SerdeKeycode {
176 message: format!(
177 "unexpected end of key at position {}: incomplete escape sequence",
178 self.position
179 ),
180 }));
181 }
182 let next_byte = self.buffer[self.position];
183 self.position += 1;
184
185 if next_byte == 0x00 {
186 result.push(0x00);
187 } else if next_byte == 0xff {
188 break;
189 } else {
190 return Err(Error::from(TypeError::SerdeKeycode {
191 message: format!(
192 "invalid escape sequence at position {}: 0xff 0x{:02x}",
193 self.position - 1,
194 next_byte
195 ),
196 }));
197 }
198 } else {
199 result.push(!byte);
200 }
201 }
202 Ok(result)
203 }
204
205 pub fn read_str(&mut self) -> Result<String> {
206 let bytes = self.read_bytes()?;
207 String::from_utf8(bytes).map_err(|e| {
208 Error::from(TypeError::SerdeKeycode {
209 message: format!("invalid UTF-8 in key at position {}: {}", self.position, e),
210 })
211 })
212 }
213
214 pub fn read_date(&mut self) -> Result<Date> {
215 let days = self.read_i32()?;
216 Date::from_days_since_epoch(days).ok_or_else(|| {
217 Error::from(TypeError::SerdeKeycode {
218 message: format!(
219 "invalid date at position {}: {} days since epoch",
220 self.position, days
221 ),
222 })
223 })
224 }
225
226 pub fn read_datetime(&mut self) -> Result<DateTime> {
227 let nanos = self.read_i64()?;
228 Ok(DateTime::from_nanos(nanos))
229 }
230
231 pub fn read_time(&mut self) -> Result<Time> {
232 let nanos = self.read_u64()?;
233 Time::from_nanos_since_midnight(nanos).ok_or_else(|| {
234 Error::from(TypeError::SerdeKeycode {
235 message: format!(
236 "invalid time at position {}: {} nanos since midnight",
237 self.position, nanos
238 ),
239 })
240 })
241 }
242
243 pub fn read_duration(&mut self) -> Result<Duration> {
244 let months = self.read_i32()?;
245 let days = self.read_i32()?;
246 let nanos = self.read_i64()?;
247 Ok(Duration::new(months, days, nanos)?)
248 }
249
250 pub fn read_identity_id(&mut self) -> Result<IdentityId> {
251 let bytes = self.read_bytes()?;
252 let uuid = Uuid::from_slice(&bytes).map_err(|e| {
253 Error::from(TypeError::SerdeKeycode {
254 message: format!("invalid IdentityId at position {}: {}", self.position, e),
255 })
256 })?;
257 let version = uuid.get_version_num();
258 if version != 7 && version != 0 {
259 return Err(Error::from(TypeError::SerdeKeycode {
260 message: format!(
261 "invalid IdentityId version {} at position {}",
262 version, self.position
263 ),
264 }));
265 }
266 Ok(IdentityId::from(Uuid7::from(uuid)))
267 }
268
269 pub fn read_uuid4(&mut self) -> Result<Uuid4> {
270 let bytes = self.read_bytes()?;
271 let uuid = Uuid::from_slice(&bytes).map_err(|e| {
272 Error::from(TypeError::SerdeKeycode {
273 message: format!("invalid Uuid4 at position {}: {}", self.position, e),
274 })
275 })?;
276 let version = uuid.get_version_num();
277 if version != 4 && version != 0 {
278 return Err(Error::from(TypeError::SerdeKeycode {
279 message: format!("invalid Uuid4 version {} at position {}", version, self.position),
280 }));
281 }
282 Ok(Uuid4::from(uuid))
283 }
284
285 pub fn read_uuid7(&mut self) -> Result<Uuid7> {
286 let bytes = self.read_bytes()?;
287 let uuid = Uuid::from_slice(&bytes).map_err(|e| {
288 Error::from(TypeError::SerdeKeycode {
289 message: format!("invalid Uuid7 at position {}: {}", self.position, e),
290 })
291 })?;
292 let version = uuid.get_version_num();
293 if version != 7 && version != 0 {
294 return Err(Error::from(TypeError::SerdeKeycode {
295 message: format!("invalid Uuid7 version {} at position {}", version, self.position),
296 }));
297 }
298 Ok(Uuid7::from(uuid))
299 }
300
301 pub fn read_blob(&mut self) -> Result<Blob> {
302 let bytes = self.read_bytes()?;
303 Ok(Blob::from(bytes))
304 }
305
306 pub fn read_decimal(&mut self) -> Result<Decimal> {
307 let precision = self.read_u8()?;
308 let scale = self.read_u8()?;
309 let unscaled = self.read_unscaled(ValueKind::Decimal, precision, scale)?;
310 Ok(Decimal::from_parts(unscaled, scale).expect("a checked unscaled value is within 76 digits"))
311 }
312
313 fn read_unscaled(&mut self, kind: ValueKind, precision: u8, scale: u8) -> Result<i256> {
314 let position = self.position;
315 let (precision, _) =
316 decode_params(precision, scale).map_err(|error| unscaled_error(position, error))?;
317 let unscaled = self.read_payload(precision)?;
318 check_unscaled(kind, unscaled, precision).map_err(|error| unscaled_error(position, error))
319 }
320
321 fn read_payload(&mut self, precision: Precision) -> Result<i256> {
322 if width(precision) == NARROW {
323 Ok(i256::from_i128(self.read_i128()?))
324 } else {
325 let bytes = self.read_exact(32)?;
326 Ok(decode_i256(bytes.try_into()?))
327 }
328 }
329
330 fn at_container_end(&mut self) -> Result<bool> {
331 if self.remaining() < 1 {
332 return Err(Error::from(TypeError::SerdeKeycode {
333 message: format!(
334 "unexpected end of key at position {}: container not terminated",
335 self.position
336 ),
337 }));
338 }
339 if self.buffer[self.position] == CONTAINER_END {
340 self.position += 1;
341 return Ok(true);
342 }
343 Ok(false)
344 }
345
346 fn read_container_items(&mut self) -> Result<Vec<Value>> {
347 let mut items = Vec::new();
348 while !self.at_container_end()? {
349 items.push(self.read_value()?);
350 }
351 Ok(items)
352 }
353
354 fn read_record_fields(&mut self) -> Result<Vec<(String, Value)>> {
355 let mut fields = Vec::new();
356 while !self.at_container_end()? {
357 let name = self.read_str()?;
358 fields.push((name, self.read_value()?));
359 }
360 Ok(fields)
361 }
362
363 pub fn read_value(&mut self) -> Result<Value> {
364 if self.remaining() < 1 {
365 return Err(Error::from(TypeError::SerdeKeycode {
366 message: format!(
367 "unexpected end of key at position {}: cannot read value type",
368 self.position
369 ),
370 }));
371 }
372
373 let type_marker = self.buffer[self.position];
374 self.position += 1;
375
376 let kind = ValueKind::from_byte(type_marker).ok_or_else(|| {
377 Error::from(TypeError::SerdeKeycode {
378 message: format!(
379 "unknown value type marker 0x{:02x} at position {}",
380 type_marker,
381 self.position - 1
382 ),
383 })
384 })?;
385
386 match kind {
387 ValueKind::None => {
388 if self.remaining() < 1 {
389 return Ok(Value::none());
390 }
391 let inner_marker = self.buffer[self.position];
392 self.position += 1;
393 let inner = TypeTag::from_byte(inner_marker)
394 .map_err(|e| {
395 Error::from(TypeError::SerdeKeycode {
396 message: format!(
397 "invalid none inner type byte 0x{:02x} at position {}: {}",
398 inner_marker,
399 self.position - 1,
400 e
401 ),
402 })
403 })?
404 .to_type()
405 .map_err(|e| {
406 Error::from(TypeError::SerdeKeycode {
407 message: format!(
408 "invalid none inner type byte 0x{:02x} at position {}: {}",
409 inner_marker,
410 self.position - 1,
411 e
412 ),
413 })
414 })?;
415 Ok(Value::none_of(inner))
416 }
417 ValueKind::Float4 => {
418 let f = self.read_f32()?;
419 Ok(Value::Float4(OrderedF32::try_from(f).map_err(|e| {
420 Error::from(TypeError::SerdeKeycode {
421 message: format!("invalid f32 at position {}: {}", self.position, e),
422 })
423 })?))
424 }
425 ValueKind::Float8 => {
426 let f = self.read_f64()?;
427 Ok(Value::Float8(OrderedF64::try_from(f).map_err(|e| {
428 Error::from(TypeError::SerdeKeycode {
429 message: format!("invalid f64 at position {}: {}", self.position, e),
430 })
431 })?))
432 }
433 ValueKind::Boolean => Ok(Value::Boolean(self.read_bool()?)),
434 ValueKind::Int1 => Ok(Value::Int1(self.read_i8()?)),
435 ValueKind::Int2 => Ok(Value::Int2(self.read_i16()?)),
436 ValueKind::Int4 => Ok(Value::Int4(self.read_i32()?)),
437 ValueKind::Int8 => Ok(Value::Int8(self.read_i64()?)),
438 ValueKind::Int16 => Ok(Value::Int16(self.read_i128()?)),
439 ValueKind::Utf8 => Ok(Value::Utf8(self.read_str()?)),
440 ValueKind::Uint1 => Ok(Value::Uint1(self.read_u8()?)),
441 ValueKind::Uint2 => Ok(Value::Uint2(self.read_u16()?)),
442 ValueKind::Uint4 => Ok(Value::Uint4(self.read_u32()?)),
443 ValueKind::Uint8 => Ok(Value::Uint8(self.read_u64()?)),
444 ValueKind::Uint16 => Ok(Value::Uint16(self.read_u128()?)),
445 ValueKind::Date => Ok(Value::Date(self.read_date()?)),
446 ValueKind::DateTime => Ok(Value::DateTime(self.read_datetime()?)),
447 ValueKind::Time => Ok(Value::Time(self.read_time()?)),
448 ValueKind::Duration => Ok(Value::Duration(self.read_duration()?)),
449 ValueKind::IdentityId => Ok(Value::IdentityId(self.read_identity_id()?)),
450 ValueKind::Uuid4 => Ok(Value::Uuid4(self.read_uuid4()?)),
451 ValueKind::Uuid7 => Ok(Value::Uuid7(self.read_uuid7()?)),
452 ValueKind::Blob => Ok(Value::Blob(self.read_blob()?)),
453 ValueKind::Decimal => Ok(Value::Decimal(self.read_decimal()?)),
454 ValueKind::List => Ok(Value::List(self.read_container_items()?)),
455 ValueKind::Tuple => Ok(Value::Tuple(self.read_container_items()?)),
456 ValueKind::Record => Ok(Value::Record(self.read_record_fields()?)),
457 ValueKind::Any | ValueKind::Type | ValueKind::Digest => {
458 Err(Error::from(TypeError::SerdeKeycode {
459 message: format!(
460 "value kind {:?} cannot be deserialized from keys (position {})",
461 kind,
462 self.position - 1
463 ),
464 }))
465 }
466 ValueKind::DictionaryId => {
467 let sub = self.read_exact(1)?[0];
468 match sub {
469 0x00 => Ok(Value::DictionaryId(DictionaryEntryId::U1(self.read_u8()?))),
470 0x01 => Ok(Value::DictionaryId(DictionaryEntryId::U2(self.read_u16()?))),
471 0x02 => Ok(Value::DictionaryId(DictionaryEntryId::U4(self.read_u32()?))),
472 0x03 => Ok(Value::DictionaryId(DictionaryEntryId::U8(self.read_u64()?))),
473 0x04 => Ok(Value::DictionaryId(DictionaryEntryId::U16(self.read_u128()?))),
474 _ => Err(Error::from(TypeError::SerdeKeycode {
475 message: format!(
476 "unknown DictionaryEntryId sub-marker 0x{:02x} at position {}",
477 sub,
478 self.position - 1
479 ),
480 })),
481 }
482 }
483 }
484 }
485
486 pub fn read_raw(&mut self, count: usize) -> Result<&'a [u8]> {
487 self.read_exact(count)
488 }
489}
490
491fn unscaled_error(position: usize, error: DecodeError) -> Error {
492 Error::from(TypeError::SerdeKeycode {
493 message: format!("invalid fixed-width number at position {position}: {error}"),
494 })
495}