Lines
98.8 %
Functions
95.29 %
Branches
100 %
#![doc = include_str!("../crate-docs.md")]
#![forbid(unsafe_code)]
#![warn(
clippy::cargo,
missing_docs,
// clippy::missing_docs_in_private_items,
clippy::pedantic,
future_incompatible,
rust_2018_idioms,
)]
#![allow(
clippy::missing_errors_doc, // TODO clippy::missing_errors_doc
clippy::option_if_let_else,
clippy::used_underscore_binding, // false positive with tracing
clippy::module_name_repetitions,
/// Types for deserializing pots.
pub mod de;
mod error;
/// Low-level interface for reading and writing the pot format.
pub mod format;
/// Types for reading data.
pub mod reader;
/// Types for serializing pots.
pub mod ser;
mod value;
use std::io::Read;
use byteorder::WriteBytesExt;
pub use self::error::Error;
pub use self::value::{OwnedValue, Value, ValueError, ValueIter};
/// A result alias that returns [`Error`].
pub type Result<T, E = Error> = std::result::Result<T, E>;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use crate::de::SymbolMapRef;
use crate::reader::IoReader;
/// Serialize `value` using Pot into a `Vec<u8>`.
///
/// ```rust
/// let serialized = pot::to_vec(&"hello world").unwrap();
/// let deserialized = pot::from_slice::<String>(&serialized).unwrap();
/// assert_eq!(deserialized, "hello world");
/// ```
#[inline]
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
Config::default().serialize(value)
}
/// Serialize `value` using Pot into `writer`.
/// let mut serialized = Vec::new();
/// pot::to_writer(&"hello world", &mut serialized).unwrap();
/// let deserialized = pot::from_reader::<String, _>(&serialized[..]).unwrap();
pub fn to_writer<T, W>(value: &T, writer: W) -> Result<()>
W: WriteBytesExt,
Config::default().serialize_into(value, writer)
/// Restores a previously Pot-serialized value from a slice.
pub fn from_slice<'a, T>(serialized: &'a [u8]) -> Result<T>
T: Deserialize<'a>,
Config::default().deserialize(serialized)
/// Restores a previously Pot-serialized value from a [`Read`] implementer.
pub fn from_reader<T, R>(reader: R) -> Result<T>
T: DeserializeOwned,
R: Read,
Config::default().deserialize_from(reader)
/// Serialization and deserialization configuration.
#[must_use]
#[derive(Clone, Debug)]
pub struct Config {
allocation_budget: usize,
compatibility: Compatibility,
impl Default for Config {
fn default() -> Self {
Self::new()
impl Config {
/// Returns the default configuration.
pub const fn new() -> Self {
Self {
allocation_budget: usize::MAX,
compatibility: Compatibility::const_default(),
/// Sets the maximum number of bytes able to be allocated. This is not
/// guaranteed to be perfectly accurate, due to the limitations of serde
/// deserializers. Pot can keep track of how many bytes it thinks its
/// allocating, but a deserializer can always allocate more memory than Pot
/// can be aware of.
/// The default allocation budget is [`usize::MAX`].
pub const fn allocation_budget(mut self, budget: usize) -> Self {
self.allocation_budget = budget;
self
/// Sets the compatibility mode for serializing and returns self.
pub const fn compatibility(mut self, compatibilty: Compatibility) -> Self {
self.compatibility = compatibilty;
/// Deserializes a value from a slice using the configured options.
pub fn deserialize<'de, T>(&self, serialized: &'de [u8]) -> Result<T>
T: Deserialize<'de>,
let mut deserializer = de::Deserializer::from_slice(serialized, self.allocation_budget)?;
let t = T::deserialize(&mut deserializer)?;
if deserializer.end_of_input() {
Ok(t)
} else {
Err(Error::TrailingBytes)
/// Deserializes a value from a [`Read`] implementer using the configured
/// options.
pub fn deserialize_from<T, R: Read>(&self, reader: R) -> Result<T>
let mut deserializer = de::Deserializer::from_read(
IoReader::new(reader),
SymbolMapRef::temporary(),
self.allocation_budget,
)?;
T::deserialize(&mut deserializer)
/// Serializes a value to a `Vec` using the configured options.
pub fn serialize<T: Serialize>(&self, value: &T) -> Result<Vec<u8>> {
let mut output = Vec::new();
self.serialize_into(value, &mut output)?;
Ok(output)
/// Serializes a value to a writer using the configured options.
#[allow(clippy::unused_self)]
pub fn serialize_into<T, W>(&self, value: &T, writer: W) -> Result<()>
let mut serializer = ser::Serializer::new_with_compatibility(writer, self.compatibility)?;
value.serialize(&mut serializer)
/// Compatibility settings for Pot.
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
#[non_exhaustive]
pub enum Compatibility {
/// Serializes data that is compatible with all versions of Pot
/// deserializers.
/// This format does not support [`Value`](crate::Value) deserialization of
/// enum variants without associated data. See [`V5`](Self::V5) for more
/// information.
Full,
/// Serializes data in the default format
/// This format has a single change in how enum variants without associated
/// data are serialized. This change allows `deserialize_any` to
/// unambiguously distinguish between variants with associated data and
/// variants without associated data.
/// This will be the default compatibility setting in `v4.0` and later. All
/// versions after `v3.0.1` are able to read this updated format.
V4,
impl Compatibility {
const fn const_default() -> Self {
Self::Full
impl Default for Compatibility {
Self::const_default()
#[cfg(test)]
mod tests;