Skip to main content

reifydb_core/encoded/
key.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	collections::{
6		Bound,
7		Bound::{Excluded, Included, Unbounded},
8	},
9	iter,
10	ops::{Deref, RangeBounds},
11};
12
13use reifydb_type::{
14	util::cowvec::CowVec,
15	value::{
16		Value,
17		blob::Blob,
18		date::Date,
19		datetime::DateTime,
20		decimal::Decimal,
21		duration::Duration,
22		identity::IdentityId,
23		int::Int,
24		row_number::RowNumber,
25		time::Time,
26		uint::Uint,
27		uuid::{Uuid4, Uuid7},
28	},
29};
30use serde::{Deserialize, Serialize};
31
32use crate::{
33	interface::catalog::{id::IndexId, primitive::PrimitiveId},
34	util::encoding::{binary::decode_binary, keycode::serializer::KeySerializer},
35};
36
37#[derive(Debug, Clone, PartialOrd, Ord, Hash, PartialEq, Eq, Serialize, Deserialize)]
38pub struct EncodedKey(pub CowVec<u8>);
39
40impl Deref for EncodedKey {
41	type Target = CowVec<u8>;
42
43	fn deref(&self) -> &Self::Target {
44		&self.0
45	}
46}
47
48impl AsRef<[u8]> for EncodedKey {
49	fn as_ref(&self) -> &[u8] {
50		self.0.as_ref()
51	}
52}
53
54impl EncodedKey {
55	pub fn new(key: impl Into<Vec<u8>>) -> Self {
56		Self(CowVec::new(key.into()))
57	}
58
59	/// Create a new builder for constructing an EncodedKey
60	pub fn builder() -> EncodedKeyBuilder {
61		EncodedKeyBuilder::new()
62	}
63
64	pub fn as_bytes(&self) -> &[u8] {
65		self.0.as_ref()
66	}
67
68	pub fn as_slice(&self) -> &[u8] {
69		self.0.as_ref()
70	}
71}
72
73/// A builder for constructing EncodedKey values using keycode encoding
74///
75/// This provides a fluent API for building composite keys with proper order-preserving encoding.
76pub struct EncodedKeyBuilder {
77	serializer: KeySerializer,
78}
79
80impl EncodedKeyBuilder {
81	/// Create a new builder
82	pub fn new() -> Self {
83		Self {
84			serializer: KeySerializer::new(),
85		}
86	}
87
88	/// Create a builder with pre-allocated capacity
89	pub fn with_capacity(capacity: usize) -> Self {
90		Self {
91			serializer: KeySerializer::with_capacity(capacity),
92		}
93	}
94
95	/// Build the EncodedKey
96	pub fn build(self) -> EncodedKey {
97		self.serializer.to_encoded_key()
98	}
99
100	/// Extend with bool value
101	pub fn bool(mut self, value: bool) -> Self {
102		self.serializer.extend_bool(value);
103		self
104	}
105
106	/// Extend with f32 value
107	pub fn f32(mut self, value: f32) -> Self {
108		self.serializer.extend_f32(value);
109		self
110	}
111
112	/// Extend with f64 value
113	pub fn f64(mut self, value: f64) -> Self {
114		self.serializer.extend_f64(value);
115		self
116	}
117
118	/// Extend with i8 value
119	pub fn i8<T: Into<i8>>(mut self, value: T) -> Self {
120		self.serializer.extend_i8(value);
121		self
122	}
123
124	/// Extend with i16 value
125	pub fn i16<T: Into<i16>>(mut self, value: T) -> Self {
126		self.serializer.extend_i16(value);
127		self
128	}
129
130	/// Extend with i32 value
131	pub fn i32<T: Into<i32>>(mut self, value: T) -> Self {
132		self.serializer.extend_i32(value);
133		self
134	}
135
136	/// Extend with i64 value
137	pub fn i64<T: Into<i64>>(mut self, value: T) -> Self {
138		self.serializer.extend_i64(value);
139		self
140	}
141
142	/// Extend with i128 value
143	pub fn i128<T: Into<i128>>(mut self, value: T) -> Self {
144		self.serializer.extend_i128(value);
145		self
146	}
147
148	/// Extend with u8 value
149	pub fn u8<T: Into<u8>>(mut self, value: T) -> Self {
150		self.serializer.extend_u8(value);
151		self
152	}
153
154	/// Extend with u16 value
155	pub fn u16<T: Into<u16>>(mut self, value: T) -> Self {
156		self.serializer.extend_u16(value);
157		self
158	}
159
160	/// Extend with u32 value
161	pub fn u32<T: Into<u32>>(mut self, value: T) -> Self {
162		self.serializer.extend_u32(value);
163		self
164	}
165
166	/// Extend with u64 value
167	pub fn u64<T: Into<u64>>(mut self, value: T) -> Self {
168		self.serializer.extend_u64(value);
169		self
170	}
171
172	/// Extend with u128 value
173	pub fn u128<T: Into<u128>>(mut self, value: T) -> Self {
174		self.serializer.extend_u128(value);
175		self
176	}
177
178	/// Extend with raw bytes (with encoding)
179	pub fn bytes<T: AsRef<[u8]>>(mut self, bytes: T) -> Self {
180		self.serializer.extend_bytes(bytes);
181		self
182	}
183
184	/// Extend with string (UTF-8 bytes)
185	pub fn str<T: AsRef<str>>(mut self, s: T) -> Self {
186		self.serializer.extend_str(s);
187		self
188	}
189
190	/// Extend with a PrimitiveId value
191	pub fn primitive_id(mut self, primitive: impl Into<PrimitiveId>) -> Self {
192		self.serializer.extend_primitive_id(primitive);
193		self
194	}
195
196	/// Extend with an IndexId value
197	pub fn index_id(mut self, index: impl Into<IndexId>) -> Self {
198		self.serializer.extend_index_id(index);
199		self
200	}
201
202	/// Extend with a serializable value using keycode encoding
203	pub fn serialize<T: Serialize>(mut self, value: &T) -> Self {
204		self.serializer.extend_serialize(value);
205		self
206	}
207
208	/// Extend with raw bytes (no encoding)
209	pub fn raw(mut self, bytes: &[u8]) -> Self {
210		self.serializer.extend_raw(bytes);
211		self
212	}
213
214	/// Get current buffer length
215	pub fn len(&self) -> usize {
216		self.serializer.len()
217	}
218
219	/// Check if buffer is empty
220	pub fn is_empty(&self) -> bool {
221		self.serializer.is_empty()
222	}
223
224	/// Extend with Date value
225	pub fn date(mut self, date: &Date) -> Self {
226		self.serializer.extend_date(date);
227		self
228	}
229
230	/// Extend with DateTime value
231	pub fn datetime(mut self, datetime: &DateTime) -> Self {
232		self.serializer.extend_datetime(datetime);
233		self
234	}
235
236	/// Extend with Time value
237	pub fn time(mut self, time: &Time) -> Self {
238		self.serializer.extend_time(time);
239		self
240	}
241
242	/// Extend with Duration value
243	pub fn duration(mut self, duration: &Duration) -> Self {
244		self.serializer.extend_duration(duration);
245		self
246	}
247
248	/// Extend with RowNumber value
249	pub fn row_number(mut self, row_number: &RowNumber) -> Self {
250		self.serializer.extend_row_number(row_number);
251		self
252	}
253
254	/// Extend with IdentityId value
255	pub fn identity_id(mut self, id: &IdentityId) -> Self {
256		self.serializer.extend_identity_id(id);
257		self
258	}
259
260	/// Extend with Uuid4 value
261	pub fn uuid4(mut self, uuid: &Uuid4) -> Self {
262		self.serializer.extend_uuid4(uuid);
263		self
264	}
265
266	/// Extend with Uuid7 value
267	pub fn uuid7(mut self, uuid: &Uuid7) -> Self {
268		self.serializer.extend_uuid7(uuid);
269		self
270	}
271
272	/// Extend with Blob value
273	pub fn blob(mut self, blob: &Blob) -> Self {
274		self.serializer.extend_blob(blob);
275		self
276	}
277
278	/// Extend with arbitrary precision Int value
279	pub fn int(mut self, int: &Int) -> Self {
280		self.serializer.extend_int(int);
281		self
282	}
283
284	/// Extend with arbitrary precision Uint value
285	pub fn uint(mut self, uint: &Uint) -> Self {
286		self.serializer.extend_uint(uint);
287		self
288	}
289
290	/// Extend with Decimal value
291	pub fn decimal(mut self, decimal: &Decimal) -> Self {
292		self.serializer.extend_decimal(decimal);
293		self
294	}
295
296	/// Extend with a Value based on its type
297	pub fn value(mut self, value: &Value) -> Self {
298		self.serializer.extend_value(value);
299		self
300	}
301}
302
303impl Default for EncodedKeyBuilder {
304	fn default() -> Self {
305		Self::new()
306	}
307}
308
309/// Trait for types that can be converted into an EncodedKey.
310/// Provides convenient conversions from common types to EncodedKey using proper order-preserving encoding.
311pub trait IntoEncodedKey {
312	fn into_encoded_key(self) -> EncodedKey;
313}
314
315// Direct passthrough for EncodedKey
316impl IntoEncodedKey for EncodedKey {
317	fn into_encoded_key(self) -> EncodedKey {
318		self
319	}
320}
321
322// String types - using extend_str for proper encoding
323impl IntoEncodedKey for &str {
324	fn into_encoded_key(self) -> EncodedKey {
325		let mut serializer = KeySerializer::new();
326		serializer.extend_str(self);
327		serializer.to_encoded_key()
328	}
329}
330
331impl IntoEncodedKey for String {
332	fn into_encoded_key(self) -> EncodedKey {
333		let mut serializer = KeySerializer::new();
334		serializer.extend_str(&self);
335		serializer.to_encoded_key()
336	}
337}
338
339// Byte arrays - using extend_bytes for escaped encoding
340impl IntoEncodedKey for Vec<u8> {
341	fn into_encoded_key(self) -> EncodedKey {
342		let mut serializer = KeySerializer::new();
343		serializer.extend_bytes(&self);
344		serializer.to_encoded_key()
345	}
346}
347
348impl IntoEncodedKey for &[u8] {
349	fn into_encoded_key(self) -> EncodedKey {
350		let mut serializer = KeySerializer::new();
351		serializer.extend_bytes(self);
352		serializer.to_encoded_key()
353	}
354}
355
356// Numeric types - using proper encoding for order preservation
357impl IntoEncodedKey for u64 {
358	fn into_encoded_key(self) -> EncodedKey {
359		let mut serializer = KeySerializer::with_capacity(8);
360		serializer.extend_u64(self);
361		serializer.to_encoded_key()
362	}
363}
364
365impl IntoEncodedKey for i64 {
366	fn into_encoded_key(self) -> EncodedKey {
367		let mut serializer = KeySerializer::with_capacity(8);
368		serializer.extend_i64(self);
369		serializer.to_encoded_key()
370	}
371}
372
373impl IntoEncodedKey for u32 {
374	fn into_encoded_key(self) -> EncodedKey {
375		let mut serializer = KeySerializer::with_capacity(4);
376		serializer.extend_u32(self);
377		serializer.to_encoded_key()
378	}
379}
380
381impl IntoEncodedKey for i32 {
382	fn into_encoded_key(self) -> EncodedKey {
383		let mut serializer = KeySerializer::with_capacity(4);
384		serializer.extend_i32(self);
385		serializer.to_encoded_key()
386	}
387}
388
389impl IntoEncodedKey for u16 {
390	fn into_encoded_key(self) -> EncodedKey {
391		let mut serializer = KeySerializer::with_capacity(2);
392		serializer.extend_u16(self);
393		serializer.to_encoded_key()
394	}
395}
396
397impl IntoEncodedKey for i16 {
398	fn into_encoded_key(self) -> EncodedKey {
399		let mut serializer = KeySerializer::with_capacity(2);
400		serializer.extend_i16(self);
401		serializer.to_encoded_key()
402	}
403}
404
405impl IntoEncodedKey for u8 {
406	fn into_encoded_key(self) -> EncodedKey {
407		let mut serializer = KeySerializer::with_capacity(1);
408		serializer.extend_u8(self);
409		serializer.to_encoded_key()
410	}
411}
412
413impl IntoEncodedKey for i8 {
414	fn into_encoded_key(self) -> EncodedKey {
415		let mut serializer = KeySerializer::with_capacity(1);
416		serializer.extend_i8(self);
417		serializer.to_encoded_key()
418	}
419}
420
421// Reference implementations for numeric types (for StateCache)
422impl IntoEncodedKey for &u64 {
423	fn into_encoded_key(self) -> EncodedKey {
424		(*self).into_encoded_key()
425	}
426}
427
428impl IntoEncodedKey for &i64 {
429	fn into_encoded_key(self) -> EncodedKey {
430		(*self).into_encoded_key()
431	}
432}
433
434impl IntoEncodedKey for &u32 {
435	fn into_encoded_key(self) -> EncodedKey {
436		(*self).into_encoded_key()
437	}
438}
439
440impl IntoEncodedKey for &i32 {
441	fn into_encoded_key(self) -> EncodedKey {
442		(*self).into_encoded_key()
443	}
444}
445
446impl IntoEncodedKey for &u16 {
447	fn into_encoded_key(self) -> EncodedKey {
448		(*self).into_encoded_key()
449	}
450}
451
452impl IntoEncodedKey for &i16 {
453	fn into_encoded_key(self) -> EncodedKey {
454		(*self).into_encoded_key()
455	}
456}
457
458impl IntoEncodedKey for &u8 {
459	fn into_encoded_key(self) -> EncodedKey {
460		(*self).into_encoded_key()
461	}
462}
463
464impl IntoEncodedKey for &i8 {
465	fn into_encoded_key(self) -> EncodedKey {
466		(*self).into_encoded_key()
467	}
468}
469
470// RowNumber implementations (for StateCache with RowNumber keys)
471impl IntoEncodedKey for RowNumber {
472	fn into_encoded_key(self) -> EncodedKey {
473		self.0.into_encoded_key()
474	}
475}
476
477impl IntoEncodedKey for &RowNumber {
478	fn into_encoded_key(self) -> EncodedKey {
479		self.0.into_encoded_key()
480	}
481}
482
483// Value types - using extend_value for proper encoding
484impl IntoEncodedKey for Value {
485	fn into_encoded_key(self) -> EncodedKey {
486		let mut serializer = KeySerializer::new();
487		serializer.extend_value(&self);
488		serializer.to_encoded_key()
489	}
490}
491
492impl IntoEncodedKey for &Value {
493	fn into_encoded_key(self) -> EncodedKey {
494		let mut serializer = KeySerializer::new();
495		serializer.extend_value(self);
496		serializer.to_encoded_key()
497	}
498}
499
500impl IntoEncodedKey for Vec<Value> {
501	fn into_encoded_key(self) -> EncodedKey {
502		let mut serializer = KeySerializer::new();
503		for value in self.iter() {
504			serializer.extend_value(value);
505		}
506		serializer.to_encoded_key()
507	}
508}
509
510impl IntoEncodedKey for &[Value] {
511	fn into_encoded_key(self) -> EncodedKey {
512		let mut serializer = KeySerializer::new();
513		for value in self.iter() {
514			serializer.extend_value(value);
515		}
516		serializer.to_encoded_key()
517	}
518}
519
520// Tuple types - composite keys
521impl IntoEncodedKey for (String, String) {
522	fn into_encoded_key(self) -> EncodedKey {
523		let mut serializer = KeySerializer::new();
524		serializer.extend_str(&self.0);
525		serializer.extend_str(&self.1);
526		serializer.to_encoded_key()
527	}
528}
529
530impl IntoEncodedKey for &(String, String) {
531	fn into_encoded_key(self) -> EncodedKey {
532		let mut serializer = KeySerializer::new();
533		serializer.extend_str(&self.0);
534		serializer.extend_str(&self.1);
535		serializer.to_encoded_key()
536	}
537}
538
539impl IntoEncodedKey for (&str, &str) {
540	fn into_encoded_key(self) -> EncodedKey {
541		let mut serializer = KeySerializer::new();
542		serializer.extend_str(self.0);
543		serializer.extend_str(self.1);
544		serializer.to_encoded_key()
545	}
546}
547
548impl IntoEncodedKey for (String, String, String) {
549	fn into_encoded_key(self) -> EncodedKey {
550		let mut serializer = KeySerializer::new();
551		serializer.extend_str(&self.0);
552		serializer.extend_str(&self.1);
553		serializer.extend_str(&self.2);
554		serializer.to_encoded_key()
555	}
556}
557
558impl IntoEncodedKey for &(String, String, String) {
559	fn into_encoded_key(self) -> EncodedKey {
560		let mut serializer = KeySerializer::new();
561		serializer.extend_str(&self.0);
562		serializer.extend_str(&self.1);
563		serializer.extend_str(&self.2);
564		serializer.to_encoded_key()
565	}
566}
567
568impl IntoEncodedKey for &String {
569	fn into_encoded_key(self) -> EncodedKey {
570		let mut serializer = KeySerializer::new();
571		serializer.extend_str(self);
572		serializer.to_encoded_key()
573	}
574}
575
576#[derive(Clone, Debug)]
577pub struct EncodedKeyRange {
578	pub start: Bound<EncodedKey>,
579	pub end: Bound<EncodedKey>,
580}
581
582impl EncodedKeyRange {
583	pub fn new(start: Bound<EncodedKey>, end: Bound<EncodedKey>) -> Self {
584		Self {
585			start,
586			end,
587		}
588	}
589
590	/// Generates a key range for a key prefix, used e.g. for prefix scans.
591	///
592	/// The exclusive end bound is generated by adding 1 to the value of the
593	/// last byte. If the last byte(s) is 0xff (so adding 1 would
594	/// saturation), we instead find the latest non-0xff byte, increment
595	/// that, and truncate the rest. If all bytes are 0xff, we scan to the
596	/// end of the range, since there can't be other prefixes after it.
597	pub fn prefix(prefix: &[u8]) -> Self {
598		let start = Bound::Included(EncodedKey::new(prefix));
599		let end = match prefix.iter().rposition(|&b| b != 0xff) {
600			Some(i) => Bound::Excluded(EncodedKey::new(
601				prefix.iter().take(i).copied().chain(iter::once(prefix[i] + 1)).collect::<Vec<_>>(),
602			)),
603			None => Bound::Unbounded,
604		};
605		Self {
606			start,
607			end,
608		}
609	}
610
611	pub fn with_prefix(&self, prefix: EncodedKey) -> Self {
612		let start = match self.start_bound() {
613			Included(key) => {
614				let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
615				prefixed.extend_from_slice(prefix.as_ref());
616				prefixed.extend_from_slice(key.as_ref());
617				Included(EncodedKey::new(prefixed))
618			}
619			Excluded(key) => {
620				let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
621				prefixed.extend_from_slice(prefix.as_ref());
622				prefixed.extend_from_slice(key.as_ref());
623				Excluded(EncodedKey::new(prefixed))
624			}
625			Unbounded => Included(prefix.clone()),
626		};
627
628		let end = match self.end_bound() {
629			Included(key) => {
630				let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
631				prefixed.extend_from_slice(prefix.as_ref());
632				prefixed.extend_from_slice(key.as_ref());
633				Included(EncodedKey::new(prefixed))
634			}
635			Excluded(key) => {
636				let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
637				prefixed.extend_from_slice(prefix.as_ref());
638				prefixed.extend_from_slice(key.as_ref());
639				Excluded(EncodedKey::new(prefixed))
640			}
641			Unbounded => match prefix.as_ref().iter().rposition(|&b| b != 0xff) {
642				Some(i) => {
643					let mut next_prefix = prefix.as_ref()[..=i].to_vec();
644					next_prefix[i] += 1;
645					Excluded(EncodedKey::new(next_prefix))
646				}
647				None => Unbounded,
648			},
649		};
650
651		EncodedKeyRange::new(start, end)
652	}
653
654	/// Constructs a key range from an optional inclusive start key to an
655	/// optional inclusive end key.
656	///
657	/// - `start`: If provided, marks the inclusive lower bound of the range. If `None`, the range is unbounded
658	///   below.
659	/// - `end`: If provided, marks the inclusive upper bound of the range. If `None`, the range is unbounded above.
660	///
661	/// This function does not modify the input keys and assumes they are
662	/// already exact keys (not prefixes). If you need to scan all keys
663	/// with a given prefix, use [`EncodedKeyRange::prefix`] instead.
664	///
665	/// Useful for scanning between two explicit keys in a sorted key-value
666	/// store.
667	pub fn start_end(start: Option<EncodedKey>, end: Option<EncodedKey>) -> Self {
668		let start = match start {
669			Some(s) => Bound::Included(s),
670			None => Bound::Unbounded,
671		};
672
673		let end = match end {
674			Some(e) => Bound::Included(e),
675			None => Bound::Unbounded,
676		};
677
678		Self {
679			start,
680			end,
681		}
682	}
683
684	/// Constructs a key range that fragments the entire keyspace.
685	///
686	/// This range has no lower or upper bounds, making it suitable for full
687	/// scans over all keys in a sorted key-value store.
688	///
689	/// Equivalent to: `..` (in Rust range syntax)
690	pub fn all() -> Self {
691		Self {
692			start: Bound::Unbounded,
693			end: Bound::Unbounded,
694		}
695	}
696
697	/// Parses a human-readable range string into a `KeyRange`.
698	///
699	/// The expected format is `<start>..[=]<end>`, where:
700	/// - `<start>` is the inclusive lower bound (optional),
701	/// - `..` separates the bounds,
702	/// - `=` after `..` makes the upper bound inclusive,
703	/// - `<end>` is the upper bound (optional).
704	///
705	/// Examples:
706	/// - `"a..z"`       => start = Included("a"), end = Excluded("z")
707	/// - `"a..=z"`      => start = Included("a"), end = Included("z")
708	/// - `"..z"`        => start = Unbounded,     end = Excluded("z")
709	/// - `"a.."`        => start = Included("a"), end = Unbounded
710	///
711	/// If parsing fails, it defaults to a degenerate range from `0xff` to
712	/// `0xff` (empty).
713	pub fn parse(str: &str) -> Self {
714		let (mut start, mut end) = (Bound::<EncodedKey>::Unbounded, Bound::<EncodedKey>::Unbounded);
715
716		// Find the ".." separator
717		if let Some(dot_pos) = str.find("..") {
718			let start_part = &str[..dot_pos];
719			let end_part = &str[dot_pos + 2..];
720
721			// Parse start bound
722			if !start_part.is_empty() {
723				start = Bound::Included(EncodedKey(decode_binary(start_part)));
724			}
725
726			// Parse end bound - check for inclusive marker "="
727			if let Some(end_str) = end_part.strip_prefix('=') {
728				// Inclusive end: "..="
729				if !end_str.is_empty() {
730					end = Bound::Included(EncodedKey(decode_binary(end_str)));
731				}
732			} else {
733				// Exclusive end: ".."
734				if !end_part.is_empty() {
735					end = Bound::Excluded(EncodedKey(decode_binary(end_part)));
736				}
737			}
738
739			Self {
740				start,
741				end,
742			}
743		} else {
744			// Invalid format - return degenerate range
745			Self {
746				start: Bound::Included(EncodedKey::new([0xff])),
747				end: Bound::Excluded(EncodedKey::new([0xff])),
748			}
749		}
750	}
751}
752
753impl RangeBounds<EncodedKey> for EncodedKeyRange {
754	fn start_bound(&self) -> Bound<&EncodedKey> {
755		self.start.as_ref()
756	}
757
758	fn end_bound(&self) -> Bound<&EncodedKey> {
759		self.end.as_ref()
760	}
761}
762
763#[cfg(test)]
764pub mod tests {
765	use std::collections::Bound;
766
767	use super::EncodedKey;
768
769	macro_rules! as_key {
770		($key:expr) => {{ EncodedKey::new(keycode::serialize(&$key)) }};
771	}
772
773	mod prefix {
774		use std::ops::Bound;
775
776		use crate::encoded::key::{
777			EncodedKeyRange,
778			tests::{excluded, included},
779		};
780
781		#[test]
782		fn test_simple() {
783			let range = EncodedKeyRange::prefix(&[0x12, 0x34]);
784			assert_eq!(range.start, included(&[0x12, 0x34]));
785			assert_eq!(range.end, excluded(&[0x12, 0x35]));
786		}
787
788		#[test]
789		fn test_with_trailing_ff() {
790			let range = EncodedKeyRange::prefix(&[0x12, 0xff]);
791			assert_eq!(range.start, included(&[0x12, 0xff]));
792			assert_eq!(range.end, excluded(&[0x13]));
793		}
794
795		#[test]
796		fn test_with_multiple_trailing_ff() {
797			let range = EncodedKeyRange::prefix(&[0x12, 0xff, 0xff]);
798			assert_eq!(range.start, included(&[0x12, 0xff, 0xff]));
799			assert_eq!(range.end, excluded(&[0x13]));
800		}
801
802		#[test]
803		fn test_all_ff() {
804			let range = EncodedKeyRange::prefix(&[0xff, 0xff]);
805			assert_eq!(range.start, included(&[0xff, 0xff]));
806			assert_eq!(range.end, Bound::Unbounded);
807		}
808
809		#[test]
810		fn test_empty() {
811			let range = EncodedKeyRange::prefix(&[]);
812			assert_eq!(range.start, included(&[]));
813			assert_eq!(range.end, Bound::Unbounded);
814		}
815
816		#[test]
817		fn test_mid_increment() {
818			let range = EncodedKeyRange::prefix(&[0x12, 0x00, 0xff]);
819			assert_eq!(range.start, included(&[0x12, 0x00, 0xff]));
820			assert_eq!(range.end, excluded(&[0x12, 0x01]));
821		}
822	}
823
824	mod start_end {
825		use std::ops::Bound;
826
827		use crate::{
828			encoded::key::{EncodedKey, EncodedKeyRange, tests::included},
829			util::encoding::keycode,
830		};
831
832		#[test]
833		fn test_start_and_end() {
834			let range = EncodedKeyRange::start_end(Some(as_key!(1)), Some(as_key!(2)));
835			assert_eq!(range.start, included(&as_key!(1)));
836			assert_eq!(range.end, included(&as_key!(2)));
837		}
838
839		#[test]
840		fn test_start_only() {
841			let range = EncodedKeyRange::start_end(Some(as_key!(1)), None);
842			assert_eq!(range.start, included(&as_key!(1)));
843			assert_eq!(range.end, Bound::Unbounded);
844		}
845
846		#[test]
847		fn test_end_only() {
848			let range = EncodedKeyRange::start_end(None, Some(as_key!(2)));
849			assert_eq!(range.start, Bound::Unbounded);
850			assert_eq!(range.end, included(&as_key!(2)));
851		}
852
853		#[test]
854		fn test_unbounded_range() {
855			let range = EncodedKeyRange::start_end(None, None);
856			assert_eq!(range.start, Bound::Unbounded);
857			assert_eq!(range.end, Bound::Unbounded);
858		}
859
860		#[test]
861		fn test_full_byte_range() {
862			let range = EncodedKeyRange::start_end(Some(as_key!(0x00)), Some(as_key!(0xff)));
863			assert_eq!(range.start, included(&as_key!(0x00)));
864			assert_eq!(range.end, included(&as_key!(0xff)));
865		}
866
867		#[test]
868		fn test_identical_bounds() {
869			let range = EncodedKeyRange::start_end(Some(as_key!(0x42)), Some(as_key!(0x42)));
870			assert_eq!(range.start, included(&as_key!(0x42)));
871			assert_eq!(range.end, included(&as_key!(0x42)));
872		}
873	}
874
875	mod all {
876		use std::ops::Bound;
877
878		use crate::encoded::key::EncodedKeyRange;
879
880		#[test]
881		fn test_is_unbounded() {
882			let range = EncodedKeyRange::all();
883			assert_eq!(range.start, Bound::Unbounded);
884			assert_eq!(range.end, Bound::Unbounded);
885		}
886	}
887
888	mod parse {
889		use std::ops::Bound;
890
891		use crate::encoded::key::{
892			EncodedKey, EncodedKeyRange,
893			tests::{excluded, included},
894		};
895
896		#[test]
897		fn test_full_range() {
898			let r = EncodedKeyRange::parse("a..z");
899			assert_eq!(r.start, included(b"a"));
900			assert_eq!(r.end, excluded(b"z"));
901		}
902
903		#[test]
904		fn test_inclusive_end() {
905			let r = EncodedKeyRange::parse("a..=z");
906			assert_eq!(r.start, included(b"a"));
907			assert_eq!(r.end, included(b"z"));
908		}
909
910		#[test]
911		fn test_unbounded_start() {
912			let r = EncodedKeyRange::parse("..z");
913			assert_eq!(r.start, Bound::Unbounded);
914			assert_eq!(r.end, excluded(b"z"));
915		}
916
917		#[test]
918		fn test_unbounded_end() {
919			let r = EncodedKeyRange::parse("a..");
920			assert_eq!(r.start, included(b"a"));
921			assert_eq!(r.end, Bound::Unbounded);
922		}
923
924		#[test]
925		fn test_inclusive_only() {
926			let r = EncodedKeyRange::parse("..=z");
927			assert_eq!(r.start, Bound::Unbounded);
928			assert_eq!(r.end, included(b"z"));
929		}
930
931		#[test]
932		fn test_invalid_string_returns_degenerate_range() {
933			let r = EncodedKeyRange::parse("not a range");
934			let expected = EncodedKey::new([0xff]);
935			assert_eq!(r.start, Bound::Included(expected.clone()));
936			assert_eq!(r.end, Bound::Excluded(expected));
937		}
938
939		#[test]
940		fn test_empty_string_returns_degenerate_range() {
941			let r = EncodedKeyRange::parse("");
942			let expected = EncodedKey::new([0xff]);
943			assert_eq!(r.start, Bound::Included(expected.clone()));
944			assert_eq!(r.end, Bound::Excluded(expected));
945		}
946
947		#[test]
948		fn test_binary_encoded_values() {
949			let r = EncodedKeyRange::parse("0101..=0aff");
950			// decode_binary("0101") = [0x01, 0x01]
951			assert_eq!(r.start, included(b"0101"));
952			// decode_binary("0aff") = [0x0a, 0xff]
953			assert_eq!(r.end, included(b"0aff"));
954		}
955	}
956
957	fn included(key: &[u8]) -> Bound<EncodedKey> {
958		Bound::Included(EncodedKey::new(key))
959	}
960
961	fn excluded(key: &[u8]) -> Bound<EncodedKey> {
962		Bound::Excluded(EncodedKey::new(key))
963	}
964}