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 114
//! 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; extern crate utf8; pub mod de; pub mod ser; pub use de::{deserialize, deserialize_from, Deserializer}; pub use 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.to_string()) } } impl StdError for Error { fn description(&self) -> &str { match *self { Error::Serialize(ref err) => err.description(), Error::Deserialize(ref err) => err.description(), } } fn cause(&self) -> Option<&StdError> { match *self { Error::Serialize(ref err) => Some(err), Error::Deserialize(ref err) => Some(err), } } }