Skip to main content

reifydb_codec/key/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4// This file includes and modifies code from the toydb project (https://github.com/erikgrinaker/toydb),
5// originally licensed under the Apache License, Version 2.0.
6// Original copyright:
7//   Copyright (c) 2024 Erik Grinaker
8//
9// The original Apache License can be found at:
10//   http://www.apache.org/licenses/LICENSE-2.0
11
12//! Order-preserving codec used to turn typed keys into the bytes that go on disk.
13//!
14//! Encoded byte sequences sort lexicographically in the same order as the logical keys they represent, so range scans
15//! over the storage tier produce results in natural key order without any decode pass. Submodules cover the
16//! catalog-specific key encodings, the generic `Serializer` and `Deserializer` pair, and per-type encoders for
17//! booleans, floats, and signed and unsigned integers.
18//!
19//! Invariant: the codec is order-preserving. For any two values `a < b` in their natural ordering, their encoded bytes
20//! must satisfy `encode(a) < encode(b)` lexicographically. Storage range queries, CDC, and replication all rely on this
21//! property; breaking it silently corrupts every range-scan-based operation in the workspace.
22
23use serde::{Deserialize, Serialize};
24
25pub mod deserialize;
26pub mod deserializer;
27pub mod encoded;
28pub mod serialize;
29pub mod serializer;
30pub mod sort;
31pub(crate) mod varint;
32
33use std::{f32, f64};
34
35use reifydb_value::{
36	Result,
37	error::{Error, TypeError},
38};
39
40use crate::key::{deserialize::Deserializer, encoded::EncodedKey, serialize::Serializer};
41
42pub trait ByteSink {
43	fn push(&mut self, byte: u8);
44	fn extend_from_slice(&mut self, slice: &[u8]);
45}
46
47impl ByteSink for Vec<u8> {
48	fn push(&mut self, byte: u8) {
49		Vec::push(self, byte);
50	}
51	fn extend_from_slice(&mut self, slice: &[u8]) {
52		Vec::extend_from_slice(self, slice);
53	}
54}
55
56impl ByteSink for EncodedKey {
57	fn push(&mut self, byte: u8) {
58		EncodedKey::push(self, byte);
59	}
60	fn extend_from_slice(&mut self, slice: &[u8]) {
61		EncodedKey::extend_from_slice(self, slice);
62	}
63}
64
65pub fn encode_bool(value: bool) -> u8 {
66	if value {
67		0x00
68	} else {
69		0x01
70	}
71}
72
73pub fn encode_f32(value: f32) -> [u8; 4] {
74	let bits = value.to_bits();
75	if value.is_sign_negative() {
76		bits.to_be_bytes()
77	} else {
78		(!(bits ^ 0x80000000)).to_be_bytes()
79	}
80}
81
82pub fn encode_f64(value: f64) -> [u8; 8] {
83	let bits = value.to_bits();
84	if value.is_sign_negative() {
85		bits.to_be_bytes()
86	} else {
87		(!(bits ^ 0x8000000000000000)).to_be_bytes()
88	}
89}
90
91pub fn encode_i8(value: i8) -> [u8; 1] {
92	(!(value as u8 ^ 0x80)).to_be_bytes()
93}
94
95pub fn encode_i16(value: i16) -> [u8; 2] {
96	(!(value as u16 ^ 0x8000)).to_be_bytes()
97}
98
99pub fn encode_i32(value: i32) -> [u8; 4] {
100	(!(value as u32 ^ 0x80000000)).to_be_bytes()
101}
102
103pub fn encode_i64(value: i64) -> [u8; 8] {
104	(!(value as u64 ^ 0x8000000000000000)).to_be_bytes()
105}
106
107pub fn encode_i64_varint<B: ByteSink>(value: i64, output: &mut B) {
108	if value >= 0 {
109		if value < 64 {
110			output.push(!(0x80 | value as u8));
111		} else if value < 8192 + 64 {
112			let v = (value - 64) as u16;
113			output.push(!(0xc0 | (v >> 8) as u8));
114			output.push(!(v as u8));
115		} else {
116			output.push(!0xfe);
117			let inv = !(value as u64);
118			output.extend_from_slice(&inv.to_be_bytes());
119		}
120	} else if value >= -64 {
121		output.push(!(0x40 | (value + 64) as u8));
122	} else if value >= -8192 - 64 {
123		let v = (value + 64 + 8192) as u16;
124		output.push(!(0x20 | (v >> 8) as u8));
125		output.push(!(v as u8));
126	} else {
127		output.push(!0x01);
128		let inv = !(value as u64);
129		output.extend_from_slice(&inv.to_be_bytes());
130	}
131}
132
133pub fn encode_i128(value: i128) -> [u8; 16] {
134	(!(value as u128 ^ 0x80000000000000000000000000000000)).to_be_bytes()
135}
136
137pub fn encode_u8(value: u8) -> u8 {
138	!value
139}
140
141pub fn encode_u16(value: u16) -> [u8; 2] {
142	(!value).to_be_bytes()
143}
144
145pub fn encode_u32(value: u32) -> [u8; 4] {
146	(!value).to_be_bytes()
147}
148
149pub fn encode_u32_varint<B: ByteSink>(value: u32, output: &mut B) {
150	encode_u64_varint(value as u64, output);
151}
152
153pub fn encode_u64(value: u64) -> [u8; 8] {
154	(!value).to_be_bytes()
155}
156
157pub fn encode_u64_varint<B: ByteSink>(value: u64, output: &mut B) {
158	if value < (1 << 7) {
159		output.push(!(value as u8));
160	} else if value < (1 << 14) {
161		output.push(!(0x80 | (value >> 8) as u8));
162		output.push(!(value as u8));
163	} else if value < (1 << 21) {
164		output.push(!(0xc0 | (value >> 16) as u8));
165		output.push(!((value >> 8) as u8));
166		output.push(!(value as u8));
167	} else if value < (1 << 28) {
168		output.push(!(0xe0 | (value >> 24) as u8));
169		output.push(!((value >> 16) as u8));
170		output.push(!((value >> 8) as u8));
171		output.push(!(value as u8));
172	} else if value < (1 << 35) {
173		output.push(!(0xf0 | (value >> 32) as u8));
174		output.push(!((value >> 24) as u8));
175		output.push(!((value >> 16) as u8));
176		output.push(!((value >> 8) as u8));
177		output.push(!(value as u8));
178	} else if value < (1 << 42) {
179		output.push(!(0xf8 | (value >> 40) as u8));
180		output.push(!((value >> 32) as u8));
181		output.push(!((value >> 24) as u8));
182		output.push(!((value >> 16) as u8));
183		output.push(!((value >> 8) as u8));
184		output.push(!(value as u8));
185	} else if value < (1 << 49) {
186		output.push(!(0xfc | (value >> 48) as u8));
187		output.push(!((value >> 40) as u8));
188		output.push(!((value >> 32) as u8));
189		output.push(!((value >> 24) as u8));
190		output.push(!((value >> 16) as u8));
191		output.push(!((value >> 8) as u8));
192		output.push(!(value as u8));
193	} else if value < (1 << 56) {
194		output.push(!(0xfe | (value >> 56) as u8));
195		output.push(!((value >> 48) as u8));
196		output.push(!((value >> 40) as u8));
197		output.push(!((value >> 32) as u8));
198		output.push(!((value >> 24) as u8));
199		output.push(!((value >> 16) as u8));
200		output.push(!((value >> 8) as u8));
201		output.push(!(value as u8));
202	} else {
203		output.push(!0xff);
204		let inv = !value;
205		output.extend_from_slice(&inv.to_be_bytes());
206	}
207}
208
209pub fn decode_i64_varint(input: &mut &[u8]) -> Result<i64> {
210	if input.is_empty() {
211		return Err(Error::from(TypeError::SerdeKeycode {
212			message: "unexpected end of key while decoding i64 varint".to_string(),
213		}));
214	}
215	let first = !input[0];
216	let len = if first >= 0x80 {
217		if first < 0xc0 {
218			1
219		} else if first < 0xfe {
220			2
221		} else {
222			9
223		}
224	} else if first >= 0x40 {
225		1
226	} else if first >= 0x20 {
227		2
228	} else {
229		9
230	};
231
232	if input.len() < len {
233		return Err(Error::from(TypeError::SerdeKeycode {
234			message: "unexpected end of key while decoding i64 varint".to_string(),
235		}));
236	}
237
238	let mut buf = [0u8; 9];
239	for (dst, &src) in buf[..len].iter_mut().zip(&input[..len]) {
240		*dst = !src;
241	}
242	let mut slice = &buf[..len];
243	let v = varint::decode_i64_varint(&mut slice).ok_or_else(|| {
244		Error::from(TypeError::SerdeKeycode {
245			message: "failed to decode signed varint".to_string(),
246		})
247	})?;
248	*input = &input[len..];
249	Ok(v)
250}
251
252pub fn decode_u64_varint(input: &mut &[u8]) -> Result<u64> {
253	if input.is_empty() {
254		return Err(Error::from(TypeError::SerdeKeycode {
255			message: "unexpected end of key while decoding varint".to_string(),
256		}));
257	}
258	let first = !input[0];
259	let prefix = first.leading_ones() as usize;
260	let len = if prefix == 0 {
261		1
262	} else if prefix < 8 {
263		prefix + 1
264	} else {
265		9
266	};
267
268	if input.len() < len {
269		return Err(Error::from(TypeError::SerdeKeycode {
270			message: "unexpected end of key while decoding varint".to_string(),
271		}));
272	}
273
274	let mut buf = [0u8; 9];
275	for (dst, &src) in buf[..len].iter_mut().zip(&input[..len]) {
276		*dst = !src;
277	}
278	let mut slice = &buf[..len];
279	let v = varint::decode_u64_varint(&mut slice).unwrap();
280	*input = &input[len..];
281	Ok(v)
282}
283
284pub fn encode_u128(value: u128) -> [u8; 16] {
285	(!value).to_be_bytes()
286}
287
288pub fn encode_u128_varint<B: ByteSink>(value: u128, output: &mut B) {
289	if value < (1 << 56) {
290		encode_u64_varint(value as u64, output);
291	} else {
292		output.push(!0xff);
293		let bytes = value.to_be_bytes();
294		let start = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
295		let sig = &bytes[start..];
296		output.push(!(sig.len() as u8));
297		for &b in sig {
298			output.push(!b);
299		}
300	}
301}
302
303pub fn decode_u128_varint(input: &mut &[u8]) -> Result<u128> {
304	if input.is_empty() {
305		return Err(Error::from(TypeError::SerdeKeycode {
306			message: "unexpected end of key while decoding u128 varint".to_string(),
307		}));
308	}
309	let first = !input[0];
310	let prefix = first.leading_ones() as usize;
311	if prefix < 8 {
312		let len = prefix + 1;
313		if input.len() < len {
314			return Err(Error::from(TypeError::SerdeKeycode {
315				message: "unexpected end of key while decoding u128 varint".to_string(),
316			}));
317		}
318		let mut buf = [0u8; 9];
319		for (dst, &src) in buf[..len].iter_mut().zip(&input[..len]) {
320			*dst = !src;
321		}
322		let mut slice = &buf[..len];
323		let v = varint::decode_u64_varint(&mut slice).ok_or_else(|| {
324			Error::from(TypeError::SerdeKeycode {
325				message: "failed to decode u128 varint".to_string(),
326			})
327		})?;
328		*input = &input[len..];
329		Ok(v as u128)
330	} else {
331		if input.len() < 2 {
332			return Err(Error::from(TypeError::SerdeKeycode {
333				message: "unexpected end of key while decoding u128 varint length".to_string(),
334			}));
335		}
336		let len = (!input[1]) as usize;
337		if len == 0 || len > 16 || input.len() < 2 + len {
338			return Err(Error::from(TypeError::SerdeKeycode {
339				message: "invalid u128 varint length".to_string(),
340			}));
341		}
342		let mut bytes = [0u8; 16];
343		for (i, &src) in input[2..2 + len].iter().enumerate() {
344			bytes[16 - len + i] = !src;
345		}
346		*input = &input[2 + len..];
347		Ok(u128::from_be_bytes(bytes))
348	}
349}
350
351pub fn encode_bytes<B: ByteSink>(bytes: &[u8], output: &mut B) {
352	let mut start = 0;
353	while let Some(pos) = bytes[start..].iter().position(|&b| b == 0xff) {
354		let end = start + pos;
355		output.extend_from_slice(&bytes[start..end]);
356		output.extend_from_slice(&[0xff, 0x00]);
357		start = end + 1;
358	}
359	output.extend_from_slice(&bytes[start..]);
360	output.extend_from_slice(&[0xff, 0xff]);
361}
362
363#[macro_export]
364macro_rules! key_prefix {
365    ($($arg:tt)*) => {
366        &EncodedKey::new((&format!($($arg)*)).as_bytes().to_vec())
367    };
368}
369
370pub fn serialize<T: Serialize>(key: &T) -> Vec<u8> {
371	let mut serializer = Serializer {
372		output: Vec::new(),
373	};
374
375	key.serialize(&mut serializer).expect("key must be serializable");
376	serializer.output
377}
378
379pub fn deserialize<'a, T: Deserialize<'a>>(input: &'a [u8]) -> Result<T> {
380	let mut deserializer = Deserializer::from_bytes(input);
381	let t = T::deserialize(&mut deserializer)?;
382	if !deserializer.input.is_empty() {
383		return Err(Error::from(TypeError::SerdeKeycode {
384			message: format!(
385				"unexpected trailing bytes {:x?} at end of key {input:x?}",
386				deserializer.input,
387			),
388		}));
389	}
390	Ok(t)
391}
392
393#[cfg(test)]
394pub mod tests {
395	use std::borrow::Cow;
396
397	const PI_F32: f32 = f32::consts::PI;
398	const PI_F64: f64 = f64::consts::PI;
399
400	use reifydb_value::{
401		util::hex::encode,
402		value::{Value, ordered_f32::OrderedF32, ordered_f64::OrderedF64},
403	};
404	use serde_bytes::ByteBuf;
405
406	use super::*;
407	use crate::key::serializer::KeySerializer;
408
409	#[test]
410	fn test_u128_varint_roundtrip_and_descending_order() {
411		let values: Vec<u128> = vec![
412			0,
413			1,
414			2,
415			126,
416			127,
417			128,
418			129,
419			(1 << 14) - 1,
420			1 << 14,
421			(1 << 21) - 1,
422			1 << 21,
423			(1 << 28) - 1,
424			1 << 28,
425			(1 << 35) - 1,
426			1 << 35,
427			(1 << 42) - 1,
428			1 << 42,
429			(1 << 49) - 1,
430			1 << 49,
431			(1 << 56) - 1,
432			1 << 56,
433			(1u128 << 63) - 1,
434			1u128 << 63,
435			u64::MAX as u128 - 1,
436			u64::MAX as u128,
437			u64::MAX as u128 + 1,
438			1u128 << 100,
439			u128::MAX - 1,
440			u128::MAX,
441		];
442
443		for &v in &values {
444			let mut buf = Vec::new();
445			encode_u128_varint(v, &mut buf);
446			let mut slice = buf.as_slice();
447			let decoded = decode_u128_varint(&mut slice).unwrap();
448			assert_eq!(decoded, v, "roundtrip failed for {}", v);
449			assert!(slice.is_empty(), "trailing bytes after decoding {}", v);
450		}
451
452		// keycode is descending: a strictly larger value must encode to a
453		// lexicographically smaller key, so a forward scan yields the max id first.
454		let mut sorted = values.clone();
455		sorted.sort();
456		sorted.dedup();
457		let mut prev: Option<(u128, Vec<u8>)> = None;
458		for &v in &sorted {
459			let mut buf = Vec::new();
460			encode_u128_varint(v, &mut buf);
461			if let Some((pv, pe)) = &prev {
462				assert!(*pv < v);
463				assert!(
464					buf < *pe,
465					"not descending: {} -> {:?} should sort before {} -> {:?}",
466					v,
467					buf,
468					pv,
469					pe
470				);
471			}
472			prev = Some((v, buf));
473		}
474	}
475
476	#[derive(Debug, Deserialize, Serialize, PartialEq)]
477	enum Key<'a> {
478		Unit,
479		NewType(String),
480		Tuple(bool, #[serde(with = "serde_bytes")] Vec<u8>, u64),
481		Cow(
482			#[serde(with = "serde_bytes")]
483			#[serde(borrow)]
484			Cow<'a, [u8]>,
485			bool,
486			#[serde(borrow)] Cow<'a, str>,
487		),
488	}
489
490	macro_rules! test_serde {
491        ( $( $name:ident: $input:expr => $expect:literal, )* ) => {
492        $(
493            #[test]
494            fn $name(){
495                let mut input = $input;
496                let expect = $expect;
497                let output = serialize(&input);
498                assert_eq!(encode(&output), expect, "encode failed");
499
500                let expect = input;
501                input = deserialize(&output).unwrap();
502                assert_eq!(input, expect, "decode failed");
503            }
504        )*
505        };
506    }
507
508	test_serde! {
509	bool_false: false => "01",
510	bool_true: true => "00",
511
512	f32_min: f32::MIN => "ff7fffff",
513	f32_neg_inf: f32::NEG_INFINITY => "ff800000",
514	f32_neg_pi: -PI_F32 => "c0490fdb",
515	f32_neg_zero: -0f32 => "80000000",
516	f32_zero: 0f32 => "7fffffff",
517	f32_pi: PI_F32 => "3fb6f024",
518	f32_max: f32::MAX => "00800000",
519	f32_inf: f32::INFINITY => "007fffff",
520
521	f64_min: f64::MIN => "ffefffffffffffff",
522	f64_neg_inf: f64::NEG_INFINITY => "fff0000000000000",
523	f64_neg_pi: -PI_F64 => "c00921fb54442d18",
524	f64_neg_zero: -0f64 => "8000000000000000",
525	f64_zero: 0f64 => "7fffffffffffffff",
526	f64_pi: PI_F64 => "3ff6de04abbbd2e7",
527	f64_max: f64::MAX => "0010000000000000",
528	f64_inf: f64::INFINITY => "000fffffffffffff",
529
530	i8_min: i8::MIN => "ff",
531	i8_neg_1: -1i8 => "80",
532	i8_0: 0i8 => "7f",
533	i8_1: 1i8 => "7e",
534	i8_max: i8::MAX => "00",
535
536	i16_min: i16::MIN => "ffff",
537	i16_neg_1: -1i16 => "8000",
538	i16_0: 0i16 => "7fff",
539	i16_1: 1i16 => "7ffe",
540	i16_max: i16::MAX => "0000",
541
542	i32_min: i32::MIN => "ffffffff",
543	i32_neg_1: -1i32 => "80000000",
544	i32_0: 0i32 => "7fffffff",
545	i32_1: 1i32 => "7ffffffe",
546	i32_max: i32::MAX => "00000000",
547
548	i64_min: i64::MIN => "fe7fffffffffffffff",
549	i64_neg_65535: -65535i64 => "fe000000000000fffe",
550	i64_neg_1: -1i64 => "80",
551	i64_0: 0i64 => "7f",
552	i64_1: 1i64 => "7e",
553	i64_65535: 65535i64 => "01ffffffffffff0000",
554	i64_max: i64::MAX => "018000000000000000",
555
556	i128_min: i128::MIN => "ffffffffffffffffffffffffffffffff",
557	i128_neg_1: -1i128 => "80000000000000000000000000000000",
558	i128_0: 0i128 => "7fffffffffffffffffffffffffffffff",
559	i128_1: 1i128 => "7ffffffffffffffffffffffffffffffe",
560	i128_max: i128::MAX => "00000000000000000000000000000000",
561
562	u8_min: u8::MIN => "ff",
563	u8_1: 1_u8 => "fe",
564	u8_255: 255_u8 => "00",
565
566	u16_min: u16::MIN => "ffff",
567	u16_1: 1_u16 => "fffe",
568	u16_255: 255_u16 => "ff00",
569	u16_65535: u16::MAX => "0000",
570
571	u32_min: u32::MIN => "ff",
572	u32_1: 1_u32 => "fe",
573	u32_65535: 65535_u32 => "3f0000",
574	u32_max: u32::MAX => "0f00000000",
575
576	u64_min: u64::MIN => "ff",
577	u64_1: 1_u64 => "fe",
578	u64_65535: 65535_u64 => "3f0000",
579	u64_max: u64::MAX => "000000000000000000",
580
581	u128_min: u128::MIN => "ffffffffffffffffffffffffffffffff",
582	u128_1: 1_u128 => "fffffffffffffffffffffffffffffffe",
583	u128_65535: 65535_u128 => "ffffffffffffffffffffffffffff0000",
584	u128_max: u128::MAX => "00000000000000000000000000000000",
585
586	bytes: ByteBuf::from(vec![0x01, 0xff]) => "01ff00ffff",
587	bytes_empty: ByteBuf::new() => "ffff",
588	bytes_escape: ByteBuf::from(vec![0x00, 0x01, 0x02]) => "000102ffff",
589
590	string: "foo".to_string() => "666f6fffff",
591	string_empty: "".to_string() => "ffff",
592	string_escape: "foo\x00bar".to_string() => "666f6f00626172ffff",
593	string_utf8: "👋".to_string() => "f09f918bffff",
594
595	tuple: (true, u64::MAX, ByteBuf::from(vec![0x00, 0x01])) => "000000000000000000000001ffff",
596	array_bool: [false, true, false] => "010001",
597	vec_bool: vec![false, true, false] => "010001",
598	vec_u64: vec![u64::MIN, u64::MAX, 65535_u64] => "ff0000000000000000003f0000",
599
600	enum_unit: Key::Unit => "00",
601	enum_newtype: Key::NewType("foo".to_string()) => "01666f6fffff",
602	enum_tuple: Key::Tuple(false, vec![0x00, 0x01], u64::MAX) => "02010001ffff000000000000000000",
603	enum_cow: Key::Cow(vec![0x00, 0x01].into(), false, String::from("foo").into()) => "030001ffff01666f6fffff",
604	enum_cow_borrow: Key::Cow([0x00, 0x01].as_slice().into(), false, "foo".into()) => "030001ffff01666f6fffff",
605
606	value_none: Value::none() => "001a",
607	value_bool: Value::Boolean(true) => "0100",
608	value_float4: Value::Float4(OrderedF32::try_from(PI_F32).unwrap()) => "023fb6f024",
609	value_float8: Value::Float8(OrderedF64::try_from(PI_F64).unwrap()) => "033ff6de04abbbd2e7",
610	value_int1: Value::Int1(-1) => "0480",
611	value_int4: Value::Int4(123456) => "067ffe1dbf",
612	value_int8: Value::Int8(31415926) => "0701fffffffffe20a189",
613	value_int16: Value::Int16(-123456789012345678901234567890i128) => "08800000018ee90ff6c373e0ee4e3f0ad1",
614	value_string: Value::Utf8("foo".to_string()) => "09666f6fffff",
615	value_uint1: Value::Uint1(255) => "0a00",
616	value_uint2: Value::Uint2(65535) => "0b0000",
617	value_uint4: Value::Uint4(4294967295) => "0c0f00000000",
618	value_uint8: Value::Uint8(18446744073709551615) => "0d000000000000000000",
619	value_uint16: Value::Uint16(340282366920938463463374607431768211455u128) => "0e00000000000000000000000000000000",
620
621	// Option<bool>
622	option_none_bool: None::<bool> => "00",
623	option_some_true: Some(true) => "0100",
624	option_some_false: Some(false) => "0101",
625
626	// Option<f32>
627	option_none_f32: None::<f32> => "00",
628	option_some_f32: Some(PI_F32) => "013fb6f024",
629
630	// Option<f64>
631	option_none_f64: None::<f64> => "00",
632	option_some_f64: Some(PI_F64) => "013ff6de04abbbd2e7",
633
634	// Option<i8>
635	option_none_i8: None::<i8> => "00",
636	option_some_i8: Some(0i8) => "017f",
637
638	// Option<i16>
639	option_none_i16: None::<i16> => "00",
640	option_some_i16: Some(0i16) => "017fff",
641
642	// Option<i32>
643	option_none_i32: None::<i32> => "00",
644	option_some_i32: Some(0i32) => "017fffffff",
645
646	// Option<i64>
647	option_none_i64: None::<i64> => "00",
648	option_some_i64: Some(0i64) => "017f",
649
650	// Option<i128>
651	option_none_i128: None::<i128> => "00",
652	option_some_i128: Some(0i128) => "017fffffffffffffffffffffffffffffff",
653
654	// Option<u8>
655	option_none_u8: None::<u8> => "00",
656	option_some_u8: Some(0u8) => "01ff",
657
658	// Option<u16>
659	option_none_u16: None::<u16> => "00",
660	option_some_u16: Some(0u16) => "01ffff",
661
662	// Option<u32>
663	option_none_u32: None::<u32> => "00",
664	option_some_u32: Some(0u32) => "01ff",
665
666	// Option<u64>
667	option_none_u64: None::<u64> => "00",
668	option_some_u64: Some(0u64) => "01ff",
669
670	// Option<u128>
671	option_none_u128: None::<u128> => "00",
672	option_some_u128: Some(0u128) => "01ffffffffffffffffffffffffffffffff",
673
674	// Option<String>
675	option_none_string: None::<String> => "00",
676	option_some_string: Some("foo".to_string()) => "01666f6fffff",
677	option_some_empty_string: Some("".to_string()) => "01ffff",
678
679	// Option<ByteBuf>
680	option_none_bytes: None::<ByteBuf> => "00",
681	option_some_bytes: Some(ByteBuf::from(vec![0x01, 0xff])) => "0101ff00ffff",
682
683	// Nested Option<Option<bool>>
684	option_nested_none: None::<Option<bool>> => "00",
685	option_nested_some_none: Some(None::<bool>) => "0100",
686	option_nested_some_some_true: Some(Some(true)) => "010100",
687	option_nested_some_some_false: Some(Some(false)) => "010101",
688
689	// Nested Option<Option<i32>>
690	option_nested_none_i32: None::<Option<i32>> => "00",
691	option_nested_some_none_i32: Some(None::<i32>) => "0100",
692	option_nested_some_some_i32: Some(Some(0i32)) => "01017fffffff",
693
694	// Nested Option<Option<String>>
695	option_nested_some_some_string: Some(Some("foo".to_string())) => "0101666f6fffff",
696
697	// Triple nested Option<Option<Option<bool>>>
698	option_triple_none: None::<Option<Option<bool>>> => "00",
699	option_triple_some_none: Some(None::<Option<bool>>) => "0100",
700	option_triple_some_some_none: Some(Some(None::<bool>)) => "010100",
701	option_triple_some_some_some: Some(Some(Some(true))) => "01010100",}
702
703	#[test]
704	fn test_option_ordering() {
705		// Descending: None > Some(MAX) > Some(0) > Some(MIN)
706		// Byte order: None < Some(MAX) < Some(0) < Some(MIN)
707		let none = serialize(&None::<i32>);
708		let some_max = serialize(&Some(i32::MAX));
709		let some_zero = serialize(&Some(0i32));
710		let some_min = serialize(&Some(i32::MIN));
711		assert!(none < some_max);
712		assert!(some_max < some_zero);
713		assert!(some_zero < some_min);
714	}
715
716	#[test]
717	fn test_nested_option_ordering() {
718		let none = serialize(&None::<Option<bool>>);
719		let some_none = serialize(&Some(None::<bool>));
720		let some_some_true = serialize(&Some(Some(true)));
721		let some_some_false = serialize(&Some(Some(false)));
722		assert!(none < some_none);
723		assert!(some_none < some_some_true);
724		assert!(some_some_true < some_some_false);
725	}
726
727	#[test]
728	fn test_key_serializer() {
729		// Test bool
730		let mut s = KeySerializer::new();
731		s.extend_bool(true);
732		assert_eq!(s.finish(), vec![0x00]);
733
734		let mut s = KeySerializer::new();
735		s.extend_bool(false);
736		assert_eq!(s.finish(), vec![0x01]);
737
738		// Test u64
739		let mut s = KeySerializer::new();
740		s.extend_u64(0u64);
741		assert_eq!(s.finish(), vec![0xff]);
742
743		// Test i64
744		let mut s = KeySerializer::new();
745		s.extend_i64(0i64);
746		assert_eq!(s.finish(), vec![0x7f]);
747
748		// Test f32
749		let mut s = KeySerializer::new();
750		s.extend_f32(0.0f32);
751		assert_eq!(s.finish(), vec![0x7f, 0xff, 0xff, 0xff]);
752
753		// Test f64
754		let mut s = KeySerializer::new();
755		s.extend_f64(0.0f64);
756		assert_eq!(s.finish(), vec![0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
757
758		// Test bytes
759		let mut s = KeySerializer::new();
760		s.extend_bytes(b"foo");
761		assert_eq!(s.finish(), vec![0x66, 0x6f, 0x6f, 0xff, 0xff]);
762
763		// Test chaining
764		let mut s = KeySerializer::with_capacity(32);
765		s.extend_bool(true).extend_u32(1u32).extend_i16(-1i16).extend_bytes(b"test");
766		let result = s.finish();
767		assert!(!result.is_empty());
768		assert!(result.len() >= 10); // Should have all the encoded values
769	}
770}