Source code

Revision control

Copy as Markdown

Other Tools

//! `bincode` uses a Builder-pattern to configure the Serializers and Deserializers in this↩
//! crate. This means that if you need to customize the behavior of `bincode`, you should create an↩
//! instance of the `DefaultOptions` struct:↩
//!↩
//! ```rust↩
//! use bincode::Options;↩
//! let my_options = bincode::DefaultOptions::new();↩
//! ```↩
//!↩
//! # Options Struct vs bincode functions↩
//!↩
//! Due to historical reasons, the default options used by the `serialize()` and `deserialize()`↩
//! family of functions are different than the default options created by the `DefaultOptions` struct:↩
//!↩
//! | | Byte limit | Endianness | Int Encoding | Trailing Behavior |↩
//! |----------|------------|------------|--------------|-------------------|↩
//! | struct | Unlimited | Little | Varint | Reject |↩
//! | function | Unlimited | Little | Fixint | Allow |↩
//!↩
//! This means that if you want to use the `Serialize` / `Deserialize` structs with the same↩
//! settings as the functions, you should adjust the `DefaultOptions` struct like so:↩
//!↩
//! ```rust↩
//! use bincode::Options;↩
//! let my_options = bincode::DefaultOptions::new()↩
//! .with_fixint_encoding()↩
//! .allow_trailing_bytes();↩
//! ```↩
use de::read::BincodeRead;↩
use error::Result;↩
use serde;↩
use std::io::{Read, Write};↩
use std::marker::PhantomData;↩
pub(crate) use self::endian::BincodeByteOrder;↩
pub(crate) use self::int::IntEncoding;↩
pub(crate) use self::internal::*;↩
pub(crate) use self::limit::SizeLimit;↩
pub(crate) use self::trailing::TrailingBytes;↩
pub use self::endian::{BigEndian, LittleEndian, NativeEndian};↩
pub use self::int::{FixintEncoding, VarintEncoding};↩
pub use self::legacy::*;↩
pub use self::limit::{Bounded, Infinite};↩
pub use self::trailing::{AllowTrailing, RejectTrailing};↩
mod endian;↩
mod int;↩
mod legacy;↩
mod limit;↩
mod trailing;↩
/// The default options for bincode serialization/deserialization.↩
///↩
/// ### Defaults↩
/// By default bincode will use little-endian encoding for multi-byte integers, and will not↩
/// limit the number of serialized/deserialized bytes.↩
///↩
/// ### Configuring `DefaultOptions`↩
///↩
/// `DefaultOptions` implements the [Options] trait, which means it exposes functions to change the behavior of bincode.↩
///↩
/// For example, if you wanted to limit the bincode deserializer to 1 kilobyte of user input:↩
///↩
/// ```rust↩
/// use bincode::Options;↩
/// let my_options = bincode::DefaultOptions::new().with_limit(1024);↩
/// ```↩
///↩
/// ### DefaultOptions struct vs. functions↩
///↩
/// The default configuration used by this struct is not the same as that used by the bincode↩
/// helper functions in the root of this crate. See the↩
/// [config](index.html#options-struct-vs-bincode-functions) module for more details↩
#[derive(Copy, Clone)]↩
pub struct DefaultOptions(Infinite);↩
impl DefaultOptions {↩
/// Get a default configuration object.↩
///↩
/// ### Default Configuration:↩
///↩
/// | Byte limit | Endianness | Int Encoding | Trailing Behavior |↩
/// |------------|------------|--------------|-------------------|↩
/// | Unlimited | Little | Varint | Reject |↩
pub fn new() -> DefaultOptions {↩
DefaultOptions(Infinite)↩
}↩
}↩
impl Default for DefaultOptions {↩
fn default() -> Self {↩
Self::new()↩
}↩
}↩
impl InternalOptions for DefaultOptions {↩
type Limit = Infinite;↩
type Endian = LittleEndian;↩
type IntEncoding = VarintEncoding;↩
type Trailing = RejectTrailing;↩
#[inline(always)]↩
fn limit(&mut self) -> &mut Infinite {↩
&mut self.0↩
}↩
}↩
/// A configuration builder trait whose options Bincode will use↩
/// while serializing and deserializing.↩
///↩
/// ### Options↩
/// Endianness: The endianness with which multi-byte integers will be read/written. *default: little endian*↩
///↩
/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited*↩
///↩
/// Int Encoding: The encoding used for numbers, enum discriminants, and lengths. *default: varint*↩
///↩
/// Trailing Behavior: The behavior when there are trailing bytes left over in a slice after deserialization. *default: reject*↩
///↩
/// ### Byte Limit Details↩
/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode↩
/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long.↩
///↩
/// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any↩
/// serialization that goes over the limit.↩
pub trait Options: InternalOptions + Sized {↩
/// Sets the byte limit to be unlimited.↩
/// This is the default.↩
fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> {↩
WithOtherLimit::new(self, Infinite)↩
}↩
/// Sets the byte limit to `limit`.↩
fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> {↩
WithOtherLimit::new(self, Bounded(limit))↩
}↩
/// Sets the endianness to little-endian↩
/// This is the default.↩
fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> {↩
WithOtherEndian::new(self)↩
}↩
/// Sets the endianness to big-endian↩
fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> {↩
WithOtherEndian::new(self)↩
}↩
/// Sets the endianness to the the machine-native endianness↩
fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> {↩
WithOtherEndian::new(self)↩
}↩
/// Sets the length encoding to varint↩
fn with_varint_encoding(self) -> WithOtherIntEncoding<Self, VarintEncoding> {↩
WithOtherIntEncoding::new(self)↩
}↩
/// Sets the length encoding to be fixed↩
fn with_fixint_encoding(self) -> WithOtherIntEncoding<Self, FixintEncoding> {↩
WithOtherIntEncoding::new(self)↩
}↩
/// Sets the deserializer to reject trailing bytes↩
fn reject_trailing_bytes(self) -> WithOtherTrailing<Self, RejectTrailing> {↩
WithOtherTrailing::new(self)↩
}↩
/// Sets the deserializer to allow trailing bytes↩
fn allow_trailing_bytes(self) -> WithOtherTrailing<Self, AllowTrailing> {↩
WithOtherTrailing::new(self)↩
}↩
/// Serializes a serializable object into a `Vec` of bytes using this configuration↩
#[inline(always)]↩
fn serialize<S: ?Sized + serde::Serialize>(self, t: &S) -> Result<Vec<u8>> {↩
::internal::serialize(t, self)↩
}↩
/// Returns the size that an object would be if serialized using Bincode with this configuration↩
#[inline(always)]↩
fn serialized_size<T: ?Sized + serde::Serialize>(self, t: &T) -> Result<u64> {↩
::internal::serialized_size(t, self)↩
}↩
/// Serializes an object directly into a `Writer` using this configuration↩
///↩
/// If the serialization would take more bytes than allowed by the size limit, an error↩
/// is returned and *no bytes* will be written into the `Writer`↩
#[inline(always)]↩
fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(self, w: W, t: &T) -> Result<()> {↩
::internal::serialize_into(w, t, self)↩
}↩
/// Deserializes a slice of bytes into an instance of `T` using this configuration↩
#[inline(always)]↩
fn deserialize<'a, T: serde::Deserialize<'a>>(self, bytes: &'a [u8]) -> Result<T> {↩
::internal::deserialize(bytes, self)↩
}↩
/// TODO: document↩
#[doc(hidden)]↩
#[inline(always)]↩
fn deserialize_in_place<'a, R, T>(self, reader: R, place: &mut T) -> Result<()>↩
where
R: BincodeRead<'a>,↩
T: serde::de::Deserialize<'a>,↩
{↩
::internal::deserialize_in_place(reader, self, place)↩
}↩
/// Deserializes a slice of bytes with state `seed` using this configuration.↩
#[inline(always)]↩
fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>(↩
self,↩
seed: T,↩
bytes: &'a [u8],↩
) -> Result<T::Value> {↩
::internal::deserialize_seed(seed, bytes, self)↩
}↩
/// Deserializes an object directly from a `Read`er using this configuration↩
///↩
/// If this returns an `Error`, `reader` may be in an invalid state.↩
#[inline(always)]↩
fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(self, reader: R) -> Result<T> {↩
::internal::deserialize_from(reader, self)↩
}↩
/// Deserializes an object directly from a `Read`er with state `seed` using this configuration↩
///↩
/// If this returns an `Error`, `reader` may be in an invalid state.↩
#[inline(always)]↩
fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>(↩
self,↩
seed: T,↩
reader: R,↩
) -> Result<T::Value> {↩
::internal::deserialize_from_seed(seed, reader, self)↩
}↩
/// Deserializes an object from a custom `BincodeRead`er using the default configuration.↩
/// It is highly recommended to use `deserialize_from` unless you need to implement↩
/// `BincodeRead` for performance reasons.↩
///↩
/// If this returns an `Error`, `reader` may be in an invalid state.↩
#[inline(always)]↩
fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>(↩
self,↩
reader: R,↩
) -> Result<T> {↩
::internal::deserialize_from_custom(reader, self)↩
}↩
/// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default↩
/// configuration. It is highly recommended to use `deserialize_from` unless you need to↩
/// implement `BincodeRead` for performance reasons.↩
///↩
/// If this returns an `Error`, `reader` may be in an invalid state.↩
#[inline(always)]↩
fn deserialize_from_custom_seed<'a, R: BincodeRead<'a>, T: serde::de::DeserializeSeed<'a>>(↩
self,↩
seed: T,↩
reader: R,↩
) -> Result<T::Value> {↩
::internal::deserialize_from_custom_seed(seed, reader, self)↩
}↩
}↩
impl<T: InternalOptions> Options for T {}↩
/// A configuration struct with a user-specified byte limit↩
#[derive(Clone, Copy)]↩
pub struct WithOtherLimit<O: Options, L: SizeLimit> {↩
_options: O,↩
pub(crate) new_limit: L,↩
}↩
/// A configuration struct with a user-specified endian order↩
#[derive(Clone, Copy)]↩
pub struct WithOtherEndian<O: Options, E: BincodeByteOrder> {↩
options: O,↩
_endian: PhantomData<E>,↩
}↩
/// A configuration struct with a user-specified length encoding↩
#[derive(Clone, Copy)]↩
pub struct WithOtherIntEncoding<O: Options, I: IntEncoding> {↩
options: O,↩
_length: PhantomData<I>,↩
}↩
/// A configuration struct with a user-specified trailing bytes behavior.↩
#[derive(Clone, Copy)]↩
pub struct WithOtherTrailing<O: Options, T: TrailingBytes> {↩
options: O,↩
_trailing: PhantomData<T>,↩
}↩
impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> {↩
#[inline(always)]↩
pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> {↩
WithOtherLimit {↩
_options: options,↩
new_limit: limit,↩
}↩
}↩
}↩
impl<O: Options, E: BincodeByteOrder> WithOtherEndian<O, E> {↩
#[inline(always)]↩
pub(crate) fn new(options: O) -> WithOtherEndian<O, E> {↩
WithOtherEndian {↩
options,↩
_endian: PhantomData,↩
}↩
}↩
}↩
impl<O: Options, I: IntEncoding> WithOtherIntEncoding<O, I> {↩
#[inline(always)]↩
pub(crate) fn new(options: O) -> WithOtherIntEncoding<O, I> {↩
WithOtherIntEncoding {↩
options,↩
_length: PhantomData,↩
}↩
}↩
}↩
impl<O: Options, T: TrailingBytes> WithOtherTrailing<O, T> {↩
#[inline(always)]↩
pub(crate) fn new(options: O) -> WithOtherTrailing<O, T> {↩
WithOtherTrailing {↩
options,↩
_trailing: PhantomData,↩
}↩
}↩
}↩
impl<O: Options, E: BincodeByteOrder + 'static> InternalOptions for WithOtherEndian<O, E> {↩
type Limit = O::Limit;↩
type Endian = E;↩
type IntEncoding = O::IntEncoding;↩
type Trailing = O::Trailing;↩
#[inline(always)]↩
fn limit(&mut self) -> &mut O::Limit {↩
self.options.limit()↩
}↩
}↩
impl<O: Options, L: SizeLimit + 'static> InternalOptions for WithOtherLimit<O, L> {↩
type Limit = L;↩
type Endian = O::Endian;↩
type IntEncoding = O::IntEncoding;↩
type Trailing = O::Trailing;↩
fn limit(&mut self) -> &mut L {↩
&mut self.new_limit↩
}↩
}↩
impl<O: Options, I: IntEncoding + 'static> InternalOptions for WithOtherIntEncoding<O, I> {↩
type Limit = O::Limit;↩
type Endian = O::Endian;↩
type IntEncoding = I;↩
type Trailing = O::Trailing;↩
fn limit(&mut self) -> &mut O::Limit {↩
self.options.limit()↩
}↩
}↩
impl<O: Options, T: TrailingBytes + 'static> InternalOptions for WithOtherTrailing<O, T> {↩
type Limit = O::Limit;↩
type Endian = O::Endian;↩
type IntEncoding = O::IntEncoding;↩
type Trailing = T;↩
fn limit(&mut self) -> &mut O::Limit {↩
self.options.limit()↩
}↩
}↩
mod internal {↩
use super::*;↩
pub trait InternalOptions {↩
type Limit: SizeLimit + 'static;↩
type Endian: BincodeByteOrder + 'static;↩
type IntEncoding: IntEncoding + 'static;↩
type Trailing: TrailingBytes + 'static;↩
fn limit(&mut self) -> &mut Self::Limit;↩
}↩
impl<'a, O: InternalOptions> InternalOptions for &'a mut O {↩
type Limit = O::Limit;↩
type Endian = O::Endian;↩
type IntEncoding = O::IntEncoding;↩
type Trailing = O::Trailing;↩
#[inline(always)]↩
fn limit(&mut self) -> &mut Self::Limit {↩
(*self).limit()↩
}↩
}↩
}↩