diff --git a/pot/Cargo.toml b/pot/Cargo.toml index 89cd310f..3a7604fa 100644 --- a/pot/Cargo.toml +++ b/pot/Cargo.toml @@ -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" @@ -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" diff --git a/pot/src/de.rs b/pot/src/de.rs index 7641ebc0..8cc593fc 100644 --- a/pot/src/de.rs +++ b/pot/src/de.rs @@ -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, @@ -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>, 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 { @@ -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, @@ -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; diff --git a/pot/src/error.rs b/pot/src/error.rs index f2650fa6..9321d57c 100644 --- a/pot/src/error.rs +++ b/pot/src/error.rs @@ -1,4 +1,5 @@ -use std::fmt::Display; +use std::fmt::{Debug, Display}; +use std::io; use std::str::Utf8Error; use std::string::FromUtf8Error; @@ -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 for Error { + fn from(err: io::Error) -> Self { + Self::Io(err) + } +} + impl ser::Error for Error { fn custom(msg: T) -> Self { Self::Message(msg.to_string()) diff --git a/pot/src/ser.rs b/pot/src/ser.rs index 8d4eee3a..980d4a82 100644 --- a/pot/src/ser.rs +++ b/pot/src/ser.rs @@ -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; @@ -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 { diff --git a/pot/src/value.rs b/pot/src/value.rs index a6ddfb0e..54e40ec4 100644 --- a/pot/src/value.rs +++ b/pot/src/value.rs @@ -1897,11 +1897,10 @@ 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, @@ -1909,10 +1908,20 @@ pub enum ValueError { 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(msg: T) -> Self where