Skip to main content

orderable_bytes/
lib.rs

1#![deny(missing_docs)]
2//! Canonical, order-preserving fixed-length byte encodings for plaintext
3//! types.
4//!
5//! Each supported type implements [`ToOrderableBytes`], which maps a
6//! value to a fixed-length byte array whose byte-wise lexicographic
7//! order agrees with the type's natural total order, and whose byte
8//! equality agrees with the type's value equality. The resulting bytes
9//! are scheme-agnostic — they're intended for any comparison-as-bytes
10//! scheme that wants to preserve plaintext order on ciphertexts (e.g.
11//! `ore-rs` BlockORE, an OPE construction, an ordered hash).
12//!
13//! Encoders are gated behind per-type feature flags so callers only pay
14//! for the dependencies they actually use.
15
16#[cfg(feature = "chrono")]
17pub mod chrono;
18#[cfg(feature = "decimal")]
19pub mod decimal;
20pub mod primitive;
21
22#[cfg(test)]
23#[macro_use]
24extern crate quickcheck;
25
26/// Maps a value to its canonical, order-preserving fixed-length byte
27/// encoding.
28///
29/// Implementors guarantee, for any `a` and `b` of the implementing type:
30///
31/// - **Equality:** byte equality of the outputs agrees with the type's
32///   value equality (`a.to_orderable_bytes() == b.to_orderable_bytes()`
33///   iff `a == b`).
34/// - **Order:** byte-wise lexicographic comparison of the outputs agrees
35///   with the type's natural total order
36///   (`a.to_orderable_bytes() <= b.to_orderable_bytes()` iff `a <= b`).
37///
38/// The encoded length is fixed per type and exposed via
39/// [`ENCODED_LEN`](Self::ENCODED_LEN). Per-type modules also re-export
40/// the same value as a free `pub const` for use in const contexts where
41/// naming the impl would be unwieldy.
42pub trait ToOrderableBytes {
43    /// Length, in bytes, of the canonical encoding produced by
44    /// [`to_orderable_bytes`](Self::to_orderable_bytes).
45    const ENCODED_LEN: usize;
46
47    /// The fixed-length byte array type returned by
48    /// [`to_orderable_bytes`](Self::to_orderable_bytes). By convention
49    /// every impl sets this to `[u8; Self::ENCODED_LEN]`; the
50    /// indirection through an associated type is only needed because
51    /// stable Rust does not yet allow naming `[u8; Self::ENCODED_LEN]`
52    /// directly in a method signature (that requires
53    /// `feature(generic_const_exprs)`).
54    type Bytes: AsRef<[u8]>;
55
56    /// Build the canonical, order-preserving fixed-length byte encoding
57    /// of `self`.
58    fn to_orderable_bytes(&self) -> Self::Bytes;
59}