Skip to main content

reifydb_codec/key/
deserializer.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use num_bigint::{BigInt, Sign};
5use reifydb_value::{
6	Result,
7	error::{Error, TypeError},
8	value::{
9		Value,
10		blob::Blob,
11		date::Date,
12		datetime::DateTime,
13		decimal::Decimal,
14		dictionary::DictionaryEntryId,
15		duration::Duration,
16		identity::IdentityId,
17		int::Int,
18		ordered_f32::OrderedF32,
19		ordered_f64::OrderedF64,
20		row_number::RowNumber,
21		time::Time,
22		uint::Uint,
23		uuid::{Uuid4, Uuid7},
24	},
25};
26use uuid::Uuid;
27
28use super::{decode_i64_varint, decode_u64_varint, decode_u128_varint, deserialize};
29use crate::tag::{TypeTag, ValueKind};
30
31pub struct KeyDeserializer<'a> {
32	buffer: &'a [u8],
33	position: usize,
34}
35
36impl<'a> KeyDeserializer<'a> {
37	pub fn from_bytes(buffer: &'a [u8]) -> Self {
38		Self {
39			buffer,
40			position: 0,
41		}
42	}
43
44	pub fn remaining(&self) -> usize {
45		self.buffer.len().saturating_sub(self.position)
46	}
47
48	pub fn is_empty(&self) -> bool {
49		self.remaining() == 0
50	}
51
52	pub fn position(&self) -> usize {
53		self.position
54	}
55
56	pub fn remaining_bytes(&self) -> &'a [u8] {
57		&self.buffer[self.position..]
58	}
59
60	fn read_exact(&mut self, count: usize) -> Result<&'a [u8]> {
61		if self.remaining() < count {
62			return Err(Error::from(TypeError::SerdeKeycode {
63				message: format!(
64					"unexpected end of key at position {}: need {} bytes, have {}",
65					self.position,
66					count,
67					self.remaining()
68				),
69			}));
70		}
71		let start = self.position;
72		self.position += count;
73		Ok(&self.buffer[start..self.position])
74	}
75
76	pub fn read_bool(&mut self) -> Result<bool> {
77		let bytes = self.read_exact(1)?;
78		deserialize::<bool>(bytes)
79	}
80
81	pub fn read_f32(&mut self) -> Result<f32> {
82		let bytes = self.read_exact(4)?;
83		deserialize::<f32>(bytes)
84	}
85
86	pub fn read_f64(&mut self) -> Result<f64> {
87		let bytes = self.read_exact(8)?;
88		deserialize::<f64>(bytes)
89	}
90
91	pub fn read_i8(&mut self) -> Result<i8> {
92		let bytes = self.read_exact(1)?;
93		deserialize::<i8>(bytes)
94	}
95
96	pub fn read_i16(&mut self) -> Result<i16> {
97		let bytes = self.read_exact(2)?;
98		deserialize::<i16>(bytes)
99	}
100
101	pub fn read_i32(&mut self) -> Result<i32> {
102		let bytes = self.read_exact(4)?;
103		deserialize::<i32>(bytes)
104	}
105
106	pub fn read_i64(&mut self) -> Result<i64> {
107		let mut slice = &self.buffer[self.position..];
108		let i = decode_i64_varint(&mut slice)?;
109		self.position = self.buffer.len() - slice.len();
110		Ok(i)
111	}
112
113	pub fn read_i128(&mut self) -> Result<i128> {
114		let bytes = self.read_exact(16)?;
115		deserialize::<i128>(bytes)
116	}
117
118	pub fn read_u8(&mut self) -> Result<u8> {
119		let bytes = self.read_exact(1)?;
120		deserialize::<u8>(bytes)
121	}
122
123	pub fn read_u16(&mut self) -> Result<u16> {
124		let bytes = self.read_exact(2)?;
125		deserialize::<u16>(bytes)
126	}
127
128	pub fn read_u32(&mut self) -> Result<u32> {
129		let mut slice = &self.buffer[self.position..];
130		let u = decode_u64_varint(&mut slice)?;
131		self.position = self.buffer.len() - slice.len();
132		Ok(u as u32)
133	}
134
135	pub fn read_u64(&mut self) -> Result<u64> {
136		let mut slice = &self.buffer[self.position..];
137		let u = decode_u64_varint(&mut slice)?;
138		self.position = self.buffer.len() - slice.len();
139		Ok(u)
140	}
141
142	pub fn read_u128(&mut self) -> Result<u128> {
143		let bytes = self.read_exact(16)?;
144		deserialize::<u128>(bytes)
145	}
146
147	pub fn read_u128_varint(&mut self) -> Result<u128> {
148		let mut slice = &self.buffer[self.position..];
149		let u = decode_u128_varint(&mut slice)?;
150		self.position = self.buffer.len() - slice.len();
151		Ok(u)
152	}
153
154	pub fn read_bytes(&mut self) -> Result<Vec<u8>> {
155		let mut result = Vec::new();
156		loop {
157			if self.remaining() < 1 {
158				return Err(Error::from(TypeError::SerdeKeycode {
159					message: format!(
160						"unexpected end of key at position {}: bytes not terminated",
161						self.position
162					),
163				}));
164			}
165			let byte = self.buffer[self.position];
166			self.position += 1;
167
168			if byte == 0xff {
169				if self.remaining() < 1 {
170					return Err(Error::from(TypeError::SerdeKeycode {
171						message: format!(
172							"unexpected end of key at position {}: incomplete escape sequence",
173							self.position
174						),
175					}));
176				}
177				let next_byte = self.buffer[self.position];
178				self.position += 1;
179
180				if next_byte == 0x00 {
181					result.push(0xff);
182				} else if next_byte == 0xff {
183					break;
184				} else {
185					return Err(Error::from(TypeError::SerdeKeycode {
186						message: format!(
187							"invalid escape sequence at position {}: 0xff 0x{:02x}",
188							self.position - 1,
189							next_byte
190						),
191					}));
192				}
193			} else {
194				result.push(byte);
195			}
196		}
197		Ok(result)
198	}
199
200	pub fn read_str(&mut self) -> Result<String> {
201		let bytes = self.read_bytes()?;
202		String::from_utf8(bytes).map_err(|e| {
203			Error::from(TypeError::SerdeKeycode {
204				message: format!("invalid UTF-8 in key at position {}: {}", self.position, e),
205			})
206		})
207	}
208
209	pub fn read_date(&mut self) -> Result<Date> {
210		let days = self.read_i32()?;
211		Date::from_days_since_epoch(days).ok_or_else(|| {
212			Error::from(TypeError::SerdeKeycode {
213				message: format!(
214					"invalid date at position {}: {} days since epoch",
215					self.position, days
216				),
217			})
218		})
219	}
220
221	pub fn read_datetime(&mut self) -> Result<DateTime> {
222		let nanos = self.read_u64()?;
223		Ok(DateTime::from_nanos(nanos))
224	}
225
226	pub fn read_time(&mut self) -> Result<Time> {
227		let nanos = self.read_u64()?;
228		Time::from_nanos_since_midnight(nanos).ok_or_else(|| {
229			Error::from(TypeError::SerdeKeycode {
230				message: format!(
231					"invalid time at position {}: {} nanos since midnight",
232					self.position, nanos
233				),
234			})
235		})
236	}
237
238	pub fn read_duration(&mut self) -> Result<Duration> {
239		let months = self.read_i32()?;
240		let days = self.read_i32()?;
241		let nanos = self.read_i64()?;
242		Ok(Duration::new(months, days, nanos)?)
243	}
244
245	pub fn read_row_number(&mut self) -> Result<RowNumber> {
246		let value = self.read_u64()?;
247		Ok(RowNumber(value))
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		Ok(IdentityId::from(Uuid7::from(uuid)))
258	}
259
260	pub fn read_uuid4(&mut self) -> Result<Uuid4> {
261		let bytes = self.read_bytes()?;
262		let uuid = Uuid::from_slice(&bytes).map_err(|e| {
263			Error::from(TypeError::SerdeKeycode {
264				message: format!("invalid Uuid4 at position {}: {}", self.position, e),
265			})
266		})?;
267		Ok(Uuid4::from(uuid))
268	}
269
270	pub fn read_uuid7(&mut self) -> Result<Uuid7> {
271		let bytes = self.read_bytes()?;
272		let uuid = Uuid::from_slice(&bytes).map_err(|e| {
273			Error::from(TypeError::SerdeKeycode {
274				message: format!("invalid Uuid7 at position {}: {}", self.position, e),
275			})
276		})?;
277		Ok(Uuid7::from(uuid))
278	}
279
280	pub fn read_blob(&mut self) -> Result<Blob> {
281		let bytes = self.read_bytes()?;
282		Ok(Blob::from(bytes))
283	}
284
285	pub fn read_int(&mut self) -> Result<Int> {
286		let sign = self.read_exact(1)?[0];
287		let len = self.read_u32()? as usize;
288		let bytes = self.read_exact(len)?;
289
290		let sign = match sign {
291			0 => Sign::Minus,
292			_ => Sign::Plus,
293		};
294
295		Ok(Int(BigInt::from_bytes_be(sign, bytes)))
296	}
297
298	pub fn read_uint(&mut self) -> Result<Uint> {
299		let len = self.read_u32()? as usize;
300		let bytes = self.read_exact(len)?;
301		Ok(Uint(BigInt::from_bytes_be(Sign::Plus, bytes)))
302	}
303
304	pub fn read_decimal(&mut self) -> Result<Decimal> {
305		let s = self.read_str()?;
306		s.parse::<Decimal>().map_err(|e| {
307			Error::from(TypeError::SerdeKeycode {
308				message: format!("invalid Decimal at position {}: {}", self.position, e),
309			})
310		})
311	}
312
313	pub fn read_value(&mut self) -> Result<Value> {
314		if self.remaining() < 1 {
315			return Err(Error::from(TypeError::SerdeKeycode {
316				message: format!(
317					"unexpected end of key at position {}: cannot read value type",
318					self.position
319				),
320			}));
321		}
322
323		let type_marker = self.buffer[self.position];
324		self.position += 1;
325
326		let kind = ValueKind::from_byte(type_marker).ok_or_else(|| {
327			Error::from(TypeError::SerdeKeycode {
328				message: format!(
329					"unknown value type marker 0x{:02x} at position {}",
330					type_marker,
331					self.position - 1
332				),
333			})
334		})?;
335
336		match kind {
337			ValueKind::None => {
338				if self.remaining() < 1 {
339					return Ok(Value::none());
340				}
341				let inner_marker = self.buffer[self.position];
342				self.position += 1;
343				let inner = TypeTag::from_byte(inner_marker)
344					.map_err(|e| {
345						Error::from(TypeError::SerdeKeycode {
346							message: format!(
347								"invalid none inner type byte 0x{:02x} at position {}: {}",
348								inner_marker,
349								self.position - 1,
350								e
351							),
352						})
353					})?
354					.to_type()
355					.map_err(|e| {
356						Error::from(TypeError::SerdeKeycode {
357							message: format!(
358								"invalid none inner type byte 0x{:02x} at position {}: {}",
359								inner_marker,
360								self.position - 1,
361								e
362							),
363						})
364					})?;
365				Ok(Value::none_of(inner))
366			}
367			ValueKind::Float4 => {
368				let f = self.read_f32()?;
369				Ok(Value::Float4(OrderedF32::try_from(f).map_err(|e| {
370					Error::from(TypeError::SerdeKeycode {
371						message: format!("invalid f32 at position {}: {}", self.position, e),
372					})
373				})?))
374			}
375			ValueKind::Float8 => {
376				let f = self.read_f64()?;
377				Ok(Value::Float8(OrderedF64::try_from(f).map_err(|e| {
378					Error::from(TypeError::SerdeKeycode {
379						message: format!("invalid f64 at position {}: {}", self.position, e),
380					})
381				})?))
382			}
383			ValueKind::Boolean => Ok(Value::Boolean(self.read_bool()?)),
384			ValueKind::Int1 => Ok(Value::Int1(self.read_i8()?)),
385			ValueKind::Int2 => Ok(Value::Int2(self.read_i16()?)),
386			ValueKind::Int4 => Ok(Value::Int4(self.read_i32()?)),
387			ValueKind::Int8 => Ok(Value::Int8(self.read_i64()?)),
388			ValueKind::Int16 => Ok(Value::Int16(self.read_i128()?)),
389			ValueKind::Utf8 => Ok(Value::Utf8(self.read_str()?)),
390			ValueKind::Uint1 => Ok(Value::Uint1(self.read_u8()?)),
391			ValueKind::Uint2 => Ok(Value::Uint2(self.read_u16()?)),
392			ValueKind::Uint4 => Ok(Value::Uint4(self.read_u32()?)),
393			ValueKind::Uint8 => Ok(Value::Uint8(self.read_u64()?)),
394			ValueKind::Uint16 => Ok(Value::Uint16(self.read_u128()?)),
395			ValueKind::Date => Ok(Value::Date(self.read_date()?)),
396			ValueKind::DateTime => Ok(Value::DateTime(self.read_datetime()?)),
397			ValueKind::Time => Ok(Value::Time(self.read_time()?)),
398			ValueKind::Duration => Ok(Value::Duration(self.read_duration()?)),
399			ValueKind::IdentityId => Ok(Value::IdentityId(self.read_identity_id()?)),
400			ValueKind::Uuid4 => Ok(Value::Uuid4(self.read_uuid4()?)),
401			ValueKind::Uuid7 => Ok(Value::Uuid7(self.read_uuid7()?)),
402			ValueKind::Blob => Ok(Value::Blob(self.read_blob()?)),
403			ValueKind::Int => Ok(Value::Int(self.read_int()?)),
404			ValueKind::Uint => Ok(Value::Uint(self.read_uint()?)),
405			ValueKind::Decimal => Ok(Value::Decimal(self.read_decimal()?)),
406			ValueKind::Any | ValueKind::Type | ValueKind::List | ValueKind::Record | ValueKind::Tuple => {
407				Err(Error::from(TypeError::SerdeKeycode {
408					message: format!(
409						"value kind {:?} cannot be deserialized from keys (position {})",
410						kind,
411						self.position - 1
412					),
413				}))
414			}
415			ValueKind::DictionaryId => {
416				let sub = self.read_exact(1)?[0];
417				match sub {
418					0x00 => Ok(Value::DictionaryId(DictionaryEntryId::U1(self.read_u8()?))),
419					0x01 => Ok(Value::DictionaryId(DictionaryEntryId::U2(self.read_u16()?))),
420					0x02 => Ok(Value::DictionaryId(DictionaryEntryId::U4(self.read_u32()?))),
421					0x03 => Ok(Value::DictionaryId(DictionaryEntryId::U8(self.read_u64()?))),
422					0x04 => Ok(Value::DictionaryId(DictionaryEntryId::U16(self.read_u128()?))),
423					_ => Err(Error::from(TypeError::SerdeKeycode {
424						message: format!(
425							"unknown DictionaryEntryId sub-marker 0x{:02x} at position {}",
426							sub,
427							self.position - 1
428						),
429					})),
430				}
431			}
432		}
433	}
434
435	pub fn read_raw(&mut self, count: usize) -> Result<&'a [u8]> {
436		self.read_exact(count)
437	}
438}
439
440#[cfg(test)]
441pub mod tests {
442	use std::f64::consts::E;
443
444	use reifydb_value::value::{
445		date::Date, datetime::DateTime, duration::Duration, row_number::RowNumber, time::Time,
446	};
447
448	use crate::key::{deserializer::KeyDeserializer, encoded::EncodedKey, serializer::KeySerializer};
449
450	#[test]
451	fn test_read_bool() {
452		let mut ser = KeySerializer::new();
453		ser.extend_bool(true).extend_bool(false);
454		let bytes = ser.finish();
455
456		let mut de = KeyDeserializer::from_bytes(&bytes);
457		assert_eq!(de.read_bool().unwrap(), true);
458		assert_eq!(de.read_bool().unwrap(), false);
459		assert!(de.is_empty());
460	}
461
462	#[test]
463	fn test_read_integers() {
464		let mut ser = KeySerializer::new();
465		ser.extend_i8(-42i8).extend_i16(-1000i16).extend_i32(100000i32).extend_i64(-1000000000i64);
466		let bytes = ser.finish();
467
468		let mut de = KeyDeserializer::from_bytes(&bytes);
469		assert_eq!(de.read_i8().unwrap(), -42);
470		assert_eq!(de.read_i16().unwrap(), -1000);
471		assert_eq!(de.read_i32().unwrap(), 100000);
472		assert_eq!(de.read_i64().unwrap(), -1000000000);
473		assert!(de.is_empty());
474	}
475
476	#[test]
477	fn test_read_unsigned() {
478		let mut ser = KeySerializer::new();
479		ser.extend_u8(255u8).extend_u16(65535u16).extend_u32(4294967295u32).extend_u64(18446744073709551615u64);
480		let bytes = ser.finish();
481
482		let mut de = KeyDeserializer::from_bytes(&bytes);
483		assert_eq!(de.read_u8().unwrap(), 255);
484		assert_eq!(de.read_u16().unwrap(), 65535);
485		assert_eq!(de.read_u32().unwrap(), 4294967295);
486		assert_eq!(de.read_u64().unwrap(), 18446744073709551615);
487		assert!(de.is_empty());
488	}
489
490	#[test]
491	fn test_read_floats() {
492		let mut ser = KeySerializer::new();
493		ser.extend_f32(3.14).extend_f64(E);
494		let bytes = ser.finish();
495
496		let mut de = KeyDeserializer::from_bytes(&bytes);
497		assert!((de.read_f32().unwrap() - 3.14).abs() < 0.001);
498		assert!((de.read_f64().unwrap() - E).abs() < 0.000001);
499		assert!(de.is_empty());
500	}
501
502	#[test]
503	fn test_read_bytes() {
504		let mut ser = KeySerializer::new();
505		ser.extend_bytes(b"hello").extend_bytes(&[0x01, 0xff, 0x02]);
506		let bytes = ser.finish();
507
508		let mut de = KeyDeserializer::from_bytes(&bytes);
509		assert_eq!(de.read_bytes().unwrap(), b"hello");
510		assert_eq!(de.read_bytes().unwrap(), vec![0x01, 0xff, 0x02]);
511		assert!(de.is_empty());
512	}
513
514	#[test]
515	fn test_read_str() {
516		let mut ser = KeySerializer::new();
517		ser.extend_str("hello world").extend_str("👋");
518		let bytes = ser.finish();
519
520		let mut de = KeyDeserializer::from_bytes(&bytes);
521		assert_eq!(de.read_str().unwrap(), "hello world");
522		assert_eq!(de.read_str().unwrap(), "👋");
523		assert!(de.is_empty());
524	}
525
526	#[test]
527	fn test_read_date() {
528		let mut ser = KeySerializer::new();
529		let date = Date::from_ymd(2024, 1, 1).unwrap();
530		ser.extend_date(&date);
531		let bytes = ser.finish();
532
533		let mut de = KeyDeserializer::from_bytes(&bytes);
534		assert_eq!(de.read_date().unwrap(), date);
535		assert!(de.is_empty());
536	}
537
538	#[test]
539	fn test_read_datetime() {
540		let mut ser = KeySerializer::new();
541		let datetime = DateTime::from_ymd_hms(2024, 1, 1, 12, 30, 45).unwrap();
542		ser.extend_datetime(&datetime);
543		let bytes = ser.finish();
544
545		let mut de = KeyDeserializer::from_bytes(&bytes);
546		assert_eq!(de.read_datetime().unwrap(), datetime);
547		assert!(de.is_empty());
548	}
549
550	#[test]
551	fn test_read_time() {
552		let mut ser = KeySerializer::new();
553		let time = Time::from_hms(12, 30, 45).unwrap();
554		ser.extend_time(&time);
555		let bytes = ser.finish();
556
557		let mut de = KeyDeserializer::from_bytes(&bytes);
558		assert_eq!(de.read_time().unwrap(), time);
559		assert!(de.is_empty());
560	}
561
562	#[test]
563	fn test_read_duration() {
564		let mut ser = KeySerializer::new();
565		let duration = Duration::from_nanoseconds(1000000).unwrap();
566		ser.extend_duration(&duration);
567		let bytes = ser.finish();
568
569		let mut de = KeyDeserializer::from_bytes(&bytes);
570		assert_eq!(de.read_duration().unwrap(), duration);
571		assert!(de.is_empty());
572	}
573
574	#[test]
575	fn test_keycode_roundtrip_with_months_and_days() {
576		let mut ser = KeySerializer::new();
577		let duration = Duration::new(12, 5, 1_000_000_000).unwrap();
578		ser.extend_duration(&duration);
579		let bytes = ser.finish();
580
581		let mut de = KeyDeserializer::from_bytes(&bytes);
582		assert_eq!(de.read_duration().unwrap(), duration);
583		assert!(de.is_empty());
584	}
585
586	#[test]
587	fn test_keycode_different_durations_produce_different_keys() {
588		let d1 = Duration::new(12, 0, 0).unwrap();
589		let d2 = Duration::zero();
590
591		let mut s1 = KeySerializer::new();
592		s1.extend_duration(&d1);
593		let b1 = s1.finish();
594
595		let mut s2 = KeySerializer::new();
596		s2.extend_duration(&d2);
597		let b2 = s2.finish();
598
599		assert_ne!(b1, b2);
600	}
601
602	#[test]
603	fn test_keycode_duration_ordering_preserved() {
604		// Keycode encoding is descending: larger Duration → smaller bytes
605		let durations = vec![
606			Duration::new(0, 0, 0).unwrap(),
607			Duration::new(0, 0, 1_000_000_000).unwrap(),
608			Duration::new(0, 1, 0).unwrap(),
609			Duration::new(1, 0, 0).unwrap(),
610			Duration::new(12, 30, 0).unwrap(),
611		];
612
613		let keys: Vec<EncodedKey> = durations
614			.iter()
615			.map(|d| {
616				let mut ser = KeySerializer::new();
617				ser.extend_duration(d);
618				ser.finish()
619			})
620			.collect();
621
622		for i in 0..keys.len() - 1 {
623			assert!(
624				keys[i] > keys[i + 1],
625				"Key ordering broken: {:?} key should be > {:?} key (descending encoding)",
626				durations[i],
627				durations[i + 1]
628			);
629		}
630	}
631
632	#[test]
633	fn test_read_row_number() {
634		let mut ser = KeySerializer::new();
635		let row = RowNumber(42);
636		ser.extend_row_number(&row);
637		let bytes = ser.finish();
638
639		let mut de = KeyDeserializer::from_bytes(&bytes);
640		assert_eq!(de.read_row_number().unwrap(), row);
641		assert!(de.is_empty());
642	}
643
644	#[test]
645	fn test_position_tracking() {
646		let mut ser = KeySerializer::new();
647		ser.extend_u8(1u8).extend_u16(2u16).extend_u32(3u32);
648		let bytes = ser.finish();
649
650		let mut de = KeyDeserializer::from_bytes(&bytes);
651		assert_eq!(de.position(), 0);
652		assert_eq!(de.remaining(), 4);
653
654		de.read_u8().unwrap();
655		assert_eq!(de.position(), 1);
656		assert_eq!(de.remaining(), 3);
657
658		de.read_u16().unwrap();
659		assert_eq!(de.position(), 3);
660		assert_eq!(de.remaining(), 1);
661
662		de.read_u32().unwrap();
663		assert_eq!(de.position(), 4);
664		assert_eq!(de.remaining(), 0);
665		assert!(de.is_empty());
666	}
667
668	#[test]
669	fn test_error_on_insufficient_bytes() {
670		let bytes = vec![0x00, 0x01];
671		let mut de = KeyDeserializer::from_bytes(&bytes);
672		assert!(de.read_u32().is_err());
673	}
674
675	#[test]
676	fn test_chaining() {
677		let mut ser = KeySerializer::new();
678		ser.extend_bool(true).extend_i32(42i32).extend_str("test").extend_u64(1000u64);
679		let bytes = ser.finish();
680
681		let mut de = KeyDeserializer::from_bytes(&bytes);
682		assert_eq!(de.read_bool().unwrap(), true);
683		assert_eq!(de.read_i32().unwrap(), 42);
684		assert_eq!(de.read_str().unwrap(), "test");
685		assert_eq!(de.read_u64().unwrap(), 1000);
686		assert!(de.is_empty());
687	}
688}