1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Binary encoding for Rust values which preserves lexicographic sort order. Order-preserving
//! encoding is useful for creating keys for sorted key-value stores with byte string typed keys,
//! such as [leveldb](https://github.com/google/leveldb) and
//! [sled](https://github.com/spacejam/sled).
//!
//! `bytekey` is *not* a self-describing format. In other words, Type information is *not*
//! serialized alongside values, and thus the type of serialized data must be known in order to
//! perform deserialization.
//!
//! #### Supported Data Types
//!
//! `bytekey` currently supports all Rust primitives, strings, options, structs, enums, vecs, and
//! tuples. See **Serializer** for details on the serialization format.
//!
//! #### Usage
//!
//! ```
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate bytekey;
//! use bytekey::{deserialize, serialize};
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct MyKey { a: u32, b: String }
//!
//! # fn main() {
//! let a = MyKey { a: 1, b: "foo".to_string() };
//! let b = MyKey { a: 2, b: "foo".to_string() };
//! let c = MyKey { a: 2, b: "fooz".to_string() };
//!
//! assert!(serialize(&a).unwrap() < serialize(&b).unwrap());
//! assert!(serialize(&b).unwrap() < serialize(&c).unwrap());
//! assert_eq!(a, deserialize(&serialize(&a).unwrap()).unwrap());
//! # }
//! ```
//!
//! #### Type Evolution
//!
//! In general, the exact type of a serialized value must be known in order to correctly
//! deserialize it. For structs and enums, the type is effectively frozen once any values of the
//! type have been serialized: changes to the struct or enum will cause deserialization of already
//! serialized values to fail or return incorrect values. The only exception is adding new variants
//! to the end of an existing enum. Enum variants may *not* change type, be removed, or be
//! reordered. All changes to structs, including adding, removing, reordering, or changing the type
//! of a field are forbidden.
//!
//! These restrictions lead to a few best-practices when using `bytekey` serialization:
//!
//! * Don't use `bytekey` unless you need lexicographic ordering of serialized values! A more
//!   general encoding library such as [Cap'n Proto](https://github.com/dwrensha/capnproto-rust) or
//!   [bincode](https://github.com/TyOverby/binary-encode) will serve you better if this feature is
//!   not necessary.
//! * If you persist serialized values for longer than the life of a process (i.e. you write the
//!   serialized values to a file or a database), consider using an enum as a top-level wrapper
//!   type. This will allow you to seamlessly add a new variant when you need to change the key
//!   format in a backwards-compatible manner (the different key types will sort seperately). If
//!   your enum has less than 16 variants, then the overhead is just a single byte in serialized
//!   output.

extern crate byteorder;
extern crate serde;

pub mod de;
pub mod ser;

pub use crate::de::{deserialize, deserialize_from, Deserializer};
pub use crate::ser::{serialize, serialize_into, Serializer};
use std::error::Error as StdError;
use std::{fmt, result};

/// An error type that encompasses both serialization and deserialization errors.
#[derive(Debug)]
pub enum Error {
    Serialize(ser::Error),
    Deserialize(de::Error),
}

/// A short-hand for `result::Result<T, bytekey::Error>`.
pub type Result<T> = result::Result<T, Error>;

impl From<ser::Error> for Error {
    fn from(error: ser::Error) -> Error {
        Error::Serialize(error)
    }
}

impl From<de::Error> for Error {
    fn from(error: de::Error) -> Error {
        Error::Deserialize(error)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.source().unwrap())
    }
}

impl StdError for Error {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match *self {
            Error::Serialize(ref err) => Some(err),
            Error::Deserialize(ref err) => Some(err),
        }
    }

    fn cause(&self) -> Option<&dyn StdError> {
        match *self {
            Error::Serialize(ref err) => Some(err),
            Error::Deserialize(ref err) => Some(err),
        }
    }
}