Skip to content

Commit

Permalink
Trimmed dependencies
Browse files Browse the repository at this point in the history
bytes was unused. this-error and derive-where save a little effort, but
I feel that once APIs have stabilized, their need of ease-of-use is less
important than being easier to compile.
  • Loading branch information
ecton committed Jul 29, 2023
1 parent 2660579 commit dadcb1d
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 31 deletions.
5 changes: 1 addition & 4 deletions pot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@ default = []

[dependencies]
serde = { version = "1.0.136", features = ["derive"] }
thiserror = "1.0.30"
tracing = { version = "0.1.30", optional = true }
byteorder = "1.4.3"
bytes = "1.1.0"
half = "2.2.1"
derive-where = "1.0.0"

[dev-dependencies]
tracing-subscriber = "0.3.8"
Expand All @@ -33,7 +30,7 @@ thousands = "0.2.0"
ciborium = "0.2.0"
bincode = "1.3.3"
rmp-serde = "1.1.0"
criterion = { version = "0.4", features = ["html_reports"] }
criterion = { version = "0.5", features = ["html_reports"] }
serde_bytes = "0.11.5"
serde_json = "1.0.78"
approx = "0.5.1"
Expand Down
25 changes: 21 additions & 4 deletions pot/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::collections::VecDeque;
use std::fmt::Debug;

use byteorder::ReadBytesExt;
use derive_where::derive_where;
use format::Kind;
use serde::de::{
self, DeserializeSeed, EnumAccess, Error as _, MapAccess, SeqAccess, VariantAccess, Visitor,
Expand All @@ -18,15 +17,23 @@ use crate::reader::{IoReader, Reader, SliceReader};
use crate::{Error, Result};

/// Deserializer for the Pot format.
#[derive_where(Debug)]
pub struct Deserializer<'s, 'de, R: Reader<'de>> {
#[derive_where(skip)]
input: R,
symbols: SymbolMap<'s, 'de>,
peeked_atom: VecDeque<Atom<'de>>,
remaining_budget: usize,
}

impl<'s, 'de, R: Reader<'de>> Debug for Deserializer<'s, 'de, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Deserializer")
.field("symbols", &self.symbols)
.field("peeked_atom", &self.peeked_atom)
.field("remaining_budget", &self.remaining_budget)
.finish()
}
}

impl<'s, 'de> Deserializer<'s, 'de, SliceReader<'de>> {
/// Returns a new deserializer for `input`.
pub(crate) fn from_slice(input: &'de [u8], maximum_bytes_allocatable: usize) -> Result<Self> {
Expand Down Expand Up @@ -823,7 +830,6 @@ impl<'de> SeqAccess<'de> for EmptyList {
}
}

#[derive_where(Debug)]
struct AtomList<'a, 's, 'de, R: Reader<'de>> {
de: &'a mut Deserializer<'s, 'de, R>,
consumed: usize,
Expand Down Expand Up @@ -864,6 +870,17 @@ impl<'a, 's, 'de, R: Reader<'de>> AtomList<'a, 's, 'de, R> {
}
}

impl<'a, 's, 'de, R: Reader<'de>> Debug for AtomList<'a, 's, 'de, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AtomList")
.field("de", &self.de)
.field("consumed", &self.consumed)
.field("count", &self.count)
.field("eof", &self.eof)
.finish()
}
}

impl<'a, 's, 'de, R: Reader<'de>> SeqAccess<'de> for AtomList<'a, 's, 'de, R> {
type Error = Error;

Expand Down
57 changes: 40 additions & 17 deletions pot/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt::Display;
use std::fmt::{Debug, Display};
use std::io;
use std::str::Utf8Error;
use std::string::FromUtf8Error;

Expand All @@ -7,52 +8,74 @@ use serde::{de, ser};
use crate::format::Kind;

/// All errors that Pot may return.
#[derive(thiserror::Error, Debug)]
#[derive(Debug)]
pub enum Error {
/// Payload is not a Pot payload.
#[error("not a pot: invalid header")]
NotAPot,
/// Data was written with an incompatible version.
#[error("incompatible version")]
IncompatibleVersion,
/// A generic error occurred.
#[error("{0}")]
Message(String),
/// Extra data appeared at the end of the input.
#[error("extra data at end of input")]
TrailingBytes,
/// Expected more data but encountered the end of the input.
#[error("unexpected end of file")]
Eof,
/// A numerical value could not be handled without losing precision or truncation.
#[error("numerical data cannot fit")]
ImpreciseCastWouldLoseData,
/// An IO error occurred.
#[error("io error: {0}")]
Io(#[from] std::io::Error),
Io(io::Error),
/// A sequence of unknown size cannot be serialized.
#[error("serializing sequences of unknown size is unsupported")]
SequenceSizeMustBeKnown,
/// String data contained invalid UTF-8 characters.
#[error("invalid utf8: {0}")]
InvalidUtf8(String),
/// An unknown kind was encountered. Generally a sign that something else has been parsed incorrectly.
#[error("invalid kind: {0}")]
InvalidKind(u8),
/// Encountered an unexpected atom kind.
#[error("encountered atom kind {0:?}, expected {1:?}")]
UnexpectedKind(Kind, Kind),
/// A requested symbol id was not found.
#[error("unknown symbol {0}")]
UnknownSymbol(u64),
/// An atom header was incorrectly formatted.
#[error("an atom header was incorrectly formatted")]
InvalidAtomHeader,
/// The amount of data read exceeds the configured maximum number of bytes.
#[error("the deserialized value is larger than the allowed allocation limit")]
TooManyBytesRead,
}

impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::NotAPot => f.write_str("not a pot: invalid header"),
Error::IncompatibleVersion => f.write_str("incompatible version"),
Error::Message(message) => f.write_str(message),
Error::TrailingBytes => f.write_str("extra data at end of input"),
Error::Eof => f.write_str("unexpected end of file"),
Error::ImpreciseCastWouldLoseData => f.write_str("numerical data cannot fit"),
Error::Io(io) => write!(f, "io error: {io}"),
Error::SequenceSizeMustBeKnown => {
f.write_str("serializing sequences of unknown size is unsupported")
}
Error::InvalidUtf8(err) => write!(f, "invalid utf8: {err}"),
Error::InvalidKind(kind) => write!(f, "invalid kind: {kind}"),
Error::UnexpectedKind(encountered, expected) => write!(
f,
"encountered atom kind {encountered:?}, expected {expected:?}"
),
Error::UnknownSymbol(sym) => write!(f, "unknown symbol {sym}"),
Error::InvalidAtomHeader => f.write_str("an atom header was incorrectly formatted"),
Error::TooManyBytesRead => {
f.write_str("the deserialized value is larger than the allowed allocation limit")
}
}
}
}

impl std::error::Error for Error {}

impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Self::Io(err)
}
}

impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Self::Message(msg.to_string())
Expand Down
12 changes: 9 additions & 3 deletions pot/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::ops::{Deref, DerefMut};
use std::usize;

use byteorder::WriteBytesExt;
use derive_where::derive_where;
use serde::{ser, Serialize};
#[cfg(feature = "tracing")]
use tracing::instrument;
Expand All @@ -12,14 +11,21 @@ use crate::format::{self, Kind, Special, CURRENT_VERSION};
use crate::{Error, Result};

/// A Pot serializer.
#[derive_where(Debug)]
pub struct Serializer<'a, W: WriteBytesExt> {
symbol_map: SymbolMapRef<'a>,
#[derive_where(skip)]
output: W,
bytes_written: usize,
}

impl<'a, W: WriteBytesExt> Debug for Serializer<'a, W> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Serializer")
.field("symbol_map", &self.symbol_map)
.field("bytes_written", &self.bytes_written)
.finish()
}
}

impl<'a, W: WriteBytesExt> Serializer<'a, W> {
/// Returns a new serializer outputting written bytes into `output`.
pub fn new(output: W) -> Result<Self> {
Expand Down
15 changes: 12 additions & 3 deletions pot/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1897,22 +1897,31 @@ impl<'de> MapAccess<'de> for MappingsDeserializer<'de> {
}

/// An error from deserializing a type using [`Value::deserialize_as`].
#[derive(thiserror::Error, Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub enum ValueError {
/// A kind of data was expected, but the [`Value`] cannot be interpreted as
/// that kind.
#[error("expected {kind} but got {value}")]
Expected {
/// The kind of data expected.
kind: &'static str,
/// The value that was encountered.
value: Value<'static>,
},
/// A custom deserialization error. These errors originate outside of Pot.
#[error("{0}")]
Custom(String),
}

impl std::error::Error for ValueError {}

impl Display for ValueError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ValueError::Expected { kind, value } => write!(f, "expected {kind} but got {value}"),
ValueError::Custom(msg) => f.write_str(msg),
}
}
}

impl serde::de::Error for ValueError {
fn custom<T>(msg: T) -> Self
where
Expand Down

0 comments on commit dadcb1d

Please sign in to comment.