heed_traits/
lib.rs

1#![doc(
2    html_favicon_url = "https://raw.githubusercontent.com/meilisearch/heed/main/assets//heed-pigeon.ico?raw=true"
3)]
4#![doc(
5    html_logo_url = "https://raw.githubusercontent.com/meilisearch/heed/main/assets/heed-pigeon-logo.png?raw=true"
6)]
7
8//! Contains the traits used to encode and decode database content.
9
10#![warn(missing_docs)]
11
12use std::borrow::Cow;
13use std::cmp::{Ord, Ordering};
14use std::error::Error as StdError;
15
16/// A boxed `Send + Sync + 'static` error.
17pub type BoxedError = Box<dyn StdError + Send + Sync + 'static>;
18
19/// A trait that represents an encoding structure.
20pub trait BytesEncode<'a> {
21    /// The type to encode.
22    type EItem: ?Sized + 'a;
23
24    /// Encode the given item as bytes.
25    fn bytes_encode(item: &'a Self::EItem) -> Result<Cow<'a, [u8]>, BoxedError>;
26}
27
28/// A trait that represents a decoding structure.
29pub trait BytesDecode<'a> {
30    /// The type to decode.
31    type DItem: 'a;
32
33    /// Decode the given bytes as `DItem`.
34    fn bytes_decode(bytes: &'a [u8]) -> Result<Self::DItem, BoxedError>;
35}
36
37/// Define a custom key comparison function for a database.
38///
39/// The comparison function is called whenever it is necessary to compare a key specified
40/// by the application with a key currently stored in the database. If no comparison function
41/// is specified, and no special key flags were specified, the keys are compared lexically,
42/// with shorter keys collating before longer keys.
43pub trait Comparator {
44    /// Compares the raw bytes representation of two keys.
45    ///
46    /// # Safety
47    ///
48    /// This function must never crash, this is the reason why it takes raw bytes as parameter,
49    /// to let you define the recovery method you want in case of a decoding error.
50    fn compare(a: &[u8], b: &[u8]) -> Ordering;
51}
52
53/// Define a lexicographic comparator, which is a special case of [`Comparator`].
54///
55/// Types that implements [`LexicographicComparator`] will automatically have [`Comparator`]
56/// implemented as well, where the [`Comparator::compare`] is implemented per the definition
57/// of lexicographic ordering with [`LexicographicComparator::compare_elem`].
58///
59/// This trait is introduced to support prefix iterators, which implicit assumes that the
60/// underlying key comparator is lexicographic.
61pub trait LexicographicComparator: Comparator {
62    /// Compare a single byte; this function is used to implement [`Comparator::compare`]
63    /// by definition of lexicographic ordering.
64    ///
65    /// # Safety
66    ///
67    /// This function must never crash.
68    fn compare_elem(a: u8, b: u8) -> Ordering;
69
70    /// Advances the given `elem` to its immediate lexicographic successor, if possible.
71    /// Returns `None` if `elem` is already at its maximum value with respect to the
72    /// lexicographic order defined by this comparator.
73    fn successor(elem: u8) -> Option<u8>;
74
75    /// Moves the given `elem` to its immediate lexicographic predecessor, if possible.
76    /// Returns `None` if `elem` is already at its minimum value with respect to the
77    /// lexicographic order defined by this comparator.
78    fn predecessor(elem: u8) -> Option<u8>;
79
80    /// Returns the maximum byte value per the comparator's lexicographic order.
81    fn max_elem() -> u8;
82
83    /// Returns the minimum byte value per the comparator's lexicographic order.
84    fn min_elem() -> u8;
85}
86
87impl<C: LexicographicComparator> Comparator for C {
88    fn compare(a: &[u8], b: &[u8]) -> Ordering {
89        for idx in 0..std::cmp::min(a.len(), b.len()) {
90            if a[idx] != b[idx] {
91                return C::compare_elem(a[idx], b[idx]);
92            }
93        }
94        Ord::cmp(&a.len(), &b.len())
95    }
96}