From 7b6f5906fb9219cab2dbbe56f70f56b24ac593fa Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Mon, 18 Mar 2024 02:45:04 +0100 Subject: [PATCH] Rework feature flags --- .github/workflows/ci.yml | 10 +++--- crates/musli-allocator/Cargo.toml | 4 +-- crates/musli-common/Cargo.toml | 4 +-- crates/musli-common/src/buf/buf_string.rs | 6 ++-- crates/musli-common/src/buf/mod.rs | 4 ++- crates/musli-common/src/context/error.rs | 6 ++-- crates/musli-common/src/context/mod.rs | 7 ++-- crates/musli-common/src/fixed_bytes.rs | 2 +- crates/musli-common/src/int/continuation.rs | 2 +- crates/musli-common/src/lib.rs | 2 +- crates/musli-common/src/reader.rs | 6 ++-- crates/musli-common/src/writer.rs | 2 +- crates/musli-descriptive/Cargo.toml | 4 +-- crates/musli-descriptive/src/error.rs | 34 +++++++++++++++---- crates/musli-json/Cargo.toml | 2 +- crates/musli-json/src/error.rs | 17 +++++++--- crates/musli-json/src/reader/integer.rs | 16 ++++----- crates/musli-json/src/reader/string.rs | 4 +-- crates/musli-serde/Cargo.toml | 4 +-- crates/musli-serde/src/deserializer.rs | 4 +-- crates/musli-serde/src/lib.rs | 3 +- crates/musli-serde/src/serializer.rs | 17 ++++++++-- crates/musli-storage/Cargo.toml | 4 +-- crates/musli-storage/src/error.rs | 6 ++-- crates/musli-value/Cargo.toml | 4 +-- crates/musli-value/src/de.rs | 36 ++++++++++----------- crates/musli-value/src/error.rs | 8 ++--- crates/musli-wire/Cargo.toml | 4 +-- crates/musli-wire/src/error.rs | 6 ++-- crates/musli-zerocopy/Cargo.toml | 4 +-- crates/musli/Cargo.toml | 4 +-- crates/musli/src/context.rs | 26 ++++++++++++--- crates/musli/src/internal/size_hint.rs | 4 +-- crates/tests/Cargo.toml | 4 +-- 34 files changed, 168 insertions(+), 102 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e284e106..ed64a9c99 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,12 +76,12 @@ jobs: steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - - run: cargo build -p ${{matrix.package}} --no-default-features - - run: cargo build -p ${{matrix.package}} --no-default-features --features alloc - - run: cargo build -p ${{matrix.package}} --no-default-features --features std - - run: cargo build -p ${{matrix.package}} --no-default-features --features simdutf8 + - run: cargo build -p ${{matrix.package}} --no-default-features -- -D warnings + - run: cargo build -p ${{matrix.package}} --no-default-features --features alloc -- -D warnings + - run: cargo build -p ${{matrix.package}} --no-default-features --features std -- -D warnings + - run: cargo build -p ${{matrix.package}} --no-default-features --features simdutf8 -- -D warnings if: matrix.package == 'musli-storage' || matrix.package == 'musli-wire' || matrix.package == 'musli-descriptive' || matrix.package == 'musli-json' - - run: cargo build -p ${{matrix.package}} --no-default-features --features parse-full + - run: cargo build -p ${{matrix.package}} --no-default-features --features parse-full -- -D warnings if: matrix.package == 'musli-json' clippy: diff --git a/crates/musli-allocator/Cargo.toml b/crates/musli-allocator/Cargo.toml index d1242e3b7..19dd4b38c 100644 --- a/crates/musli-allocator/Cargo.toml +++ b/crates/musli-allocator/Cargo.toml @@ -15,8 +15,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["memory-management", "no-std", "rust-patterns"] [features] -default = ["std"] -std = ["alloc", "musli/std"] +default = ["std", "alloc"] +std = ["musli/std"] alloc = ["musli/alloc"] [dependencies] diff --git a/crates/musli-common/Cargo.toml b/crates/musli-common/Cargo.toml index 5ddf32624..bdb30ca5d 100644 --- a/crates/musli-common/Cargo.toml +++ b/crates/musli-common/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std"] -std = ["alloc", "musli/std", "simdutf8?/std", "musli-allocator/std"] +default = ["std", "alloc"] +std = ["musli/std", "simdutf8?/std", "musli-allocator/std"] alloc = ["musli-allocator/alloc"] [dependencies] diff --git a/crates/musli-common/src/buf/buf_string.rs b/crates/musli-common/src/buf/buf_string.rs index 0a21d675d..316312b31 100644 --- a/crates/musli-common/src/buf/buf_string.rs +++ b/crates/musli-common/src/buf/buf_string.rs @@ -6,8 +6,8 @@ use musli::Buf; use crate::fixed::CapacityError; -/// A string around a buffer. -pub(crate) struct BufString { +/// A string wrapped around a context buffer. +pub struct BufString { buf: B, } @@ -16,7 +16,7 @@ where B: Buf, { /// Construct a new fixed string. - pub(crate) const fn new(buf: B) -> BufString { + pub const fn new(buf: B) -> BufString { BufString { buf } } diff --git a/crates/musli-common/src/buf/mod.rs b/crates/musli-common/src/buf/mod.rs index 27f94473f..83fc0f8ff 100644 --- a/crates/musli-common/src/buf/mod.rs +++ b/crates/musli-common/src/buf/mod.rs @@ -1,2 +1,4 @@ +//! Utilitioes for working with buffers. + mod buf_string; -pub(crate) use self::buf_string::BufString; +pub use self::buf_string::BufString; diff --git a/crates/musli-common/src/context/error.rs b/crates/musli-common/src/context/error.rs index b78ccb92b..5900a083d 100644 --- a/crates/musli-common/src/context/error.rs +++ b/crates/musli-common/src/context/error.rs @@ -7,6 +7,8 @@ use core::fmt; +use musli::context::StdError; + #[cfg(feature = "alloc")] use alloc::string::{String, ToString}; @@ -15,7 +17,7 @@ pub trait Error: Sized + 'static + Send + Sync + fmt::Display + fmt::Debug { /// Construct a custom error. fn custom(error: T) -> Self where - T: 'static + Send + Sync + fmt::Display + fmt::Debug; + T: 'static + Send + Sync + StdError; /// Collect an error from something that can be displayed. /// @@ -26,7 +28,7 @@ pub trait Error: Sized + 'static + Send + Sync + fmt::Display + fmt::Debug { T: fmt::Display; } -#[cfg(feature = "std")] +#[cfg(all(feature = "std", feature = "alloc"))] impl Error for std::io::Error { fn custom(message: T) -> Self where diff --git a/crates/musli-common/src/context/mod.rs b/crates/musli-common/src/context/mod.rs index e50948c8e..51b86229e 100644 --- a/crates/musli-common/src/context/mod.rs +++ b/crates/musli-common/src/context/mod.rs @@ -14,6 +14,7 @@ use core::cell::{Cell, UnsafeCell}; use core::fmt; use core::marker::PhantomData; +use musli::context::StdError; use musli::mode::DefaultMode; use musli::{Allocator, Context}; @@ -84,7 +85,7 @@ where #[inline] fn custom(&self, message: T) -> Self::Error where - T: 'static + Send + Sync + fmt::Display + fmt::Debug, + T: 'static + Send + Sync + StdError, { E::custom(message) } @@ -146,7 +147,7 @@ where /// Construct an error or panic. pub fn unwrap(self) -> E { if self.error.get() { - return E::custom("error"); + return E::message("error"); } panic!("did not error") @@ -231,7 +232,7 @@ where #[inline] fn custom(&self, error: T) -> ErrorMarker where - T: 'static + Send + Sync + fmt::Display + fmt::Debug, + T: 'static + Send + Sync + StdError, { // SAFETY: We're restricting access to the context, so that this is // safe. diff --git a/crates/musli-common/src/fixed_bytes.rs b/crates/musli-common/src/fixed_bytes.rs index f2c392454..2396a73eb 100644 --- a/crates/musli-common/src/fixed_bytes.rs +++ b/crates/musli-common/src/fixed_bytes.rs @@ -160,7 +160,7 @@ impl FixedBytes { C: ?Sized + Context, { if !self.extend_from_slice(source) { - return Err(cx.custom(FixedBytesOverflow { + return Err(cx.message(FixedBytesOverflow { at: self.init, additional: source.len(), capacity: N, diff --git a/crates/musli-common/src/int/continuation.rs b/crates/musli-common/src/int/continuation.rs index a6a38c8e9..fd4c4b647 100644 --- a/crates/musli-common/src/int/continuation.rs +++ b/crates/musli-common/src/int/continuation.rs @@ -54,7 +54,7 @@ where shift += 7; if shift >= T::BITS { - return Err(cx.custom("Bits overflow")); + return Err(cx.message("Bits overflow")); } b = r.read_byte(cx)?; diff --git a/crates/musli-common/src/lib.rs b/crates/musli-common/src/lib.rs index e2f36d373..ca122fddb 100644 --- a/crates/musli-common/src/lib.rs +++ b/crates/musli-common/src/lib.rs @@ -34,7 +34,7 @@ pub mod fixed_bytes; pub mod int; #[macro_use] pub mod options; -mod buf; +pub mod buf; pub mod reader; pub mod str; pub mod wrap; diff --git a/crates/musli-common/src/reader.rs b/crates/musli-common/src/reader.rs index ecf698f23..2f9352e95 100644 --- a/crates/musli-common/src/reader.rs +++ b/crates/musli-common/src/reader.rs @@ -174,7 +174,7 @@ impl<'de> Reader<'de> for &'de [u8] { C: ?Sized + Context, { if self.len() < n { - return Err(cx.custom(SliceUnderflow { + return Err(cx.message(SliceUnderflow { n, remaining: self.len(), })); @@ -348,7 +348,7 @@ where let outcome = range.start.wrapping_add(len); if outcome > range.end || outcome < range.start { - Err(cx.custom(SliceUnderflow { + Err(cx.message(SliceUnderflow { n: len, remaining: (range.end as usize).wrapping_sub(range.start as usize), })) @@ -385,7 +385,7 @@ where self.remaining = remaining; Ok(()) } - None => Err(cx.custom("Reader out of bounds")), + None => Err(cx.message("Reader out of bounds")), } } } diff --git a/crates/musli-common/src/writer.rs b/crates/musli-common/src/writer.rs index 117fdc505..3a88473f4 100644 --- a/crates/musli-common/src/writer.rs +++ b/crates/musli-common/src/writer.rs @@ -172,7 +172,7 @@ impl Writer for &mut [u8] { C: ?Sized + Context, { if self.len() < bytes.len() { - return Err(cx.custom(SliceOverflow { + return Err(cx.message(SliceOverflow { n: bytes.len(), capacity: self.len(), })); diff --git a/crates/musli-descriptive/Cargo.toml b/crates/musli-descriptive/Cargo.toml index 36535486f..f7da13779 100644 --- a/crates/musli-descriptive/Cargo.toml +++ b/crates/musli-descriptive/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std", "simdutf8"] -std = ["alloc", "musli/std", "musli-common/std", "musli-storage/std"] +default = ["std", "alloc", "simdutf8"] +std = ["musli/std", "musli-common/std", "musli-storage/std"] alloc = ["musli/alloc", "musli-common/alloc", "musli-storage/alloc"] test = [] simdutf8 = ["musli-common/simdutf8"] diff --git a/crates/musli-descriptive/src/error.rs b/crates/musli-descriptive/src/error.rs index 031aaa075..23026f798 100644 --- a/crates/musli-descriptive/src/error.rs +++ b/crates/musli-descriptive/src/error.rs @@ -5,6 +5,8 @@ use alloc::boxed::Box; #[cfg(feature = "alloc")] use alloc::string::ToString; +use musli::context::StdError; + /// Error raised during descriptive encoding. #[derive(Debug)] pub struct Error { @@ -22,8 +24,10 @@ impl fmt::Display for Error { enum ErrorImpl { #[cfg(feature = "alloc")] Message(Box), + #[cfg(feature = "alloc")] + Custom(Box), #[cfg(not(feature = "alloc"))] - Message, + Empty, } impl fmt::Display for ErrorImpl { @@ -31,22 +35,38 @@ impl fmt::Display for ErrorImpl { match self { #[cfg(feature = "alloc")] ErrorImpl::Message(message) => message.fmt(f), + #[cfg(feature = "alloc")] + ErrorImpl::Custom(message) => message.fmt(f), #[cfg(not(feature = "alloc"))] - ErrorImpl::Message => write!(f, "Message error (see diagnostics)"), + ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"), } } } -#[cfg(feature = "std")] -impl std::error::Error for Error {} +#[cfg(all(feature = "std", feature = "alloc"))] +impl std::error::Error for Error { + #[inline] + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match &self.err { + ErrorImpl::Custom(err) => Some(&**err), + _ => None, + } + } +} impl musli_common::context::Error for Error { #[inline] + #[allow(unused_variables)] fn custom(error: T) -> Self where - T: fmt::Display, + T: 'static + Send + Sync + StdError, { - Self::message(error) + Self { + #[cfg(feature = "alloc")] + err: ErrorImpl::Custom(Box::new(error)), + #[cfg(not(feature = "alloc"))] + err: ErrorImpl::Empty, + } } #[inline] @@ -59,7 +79,7 @@ impl musli_common::context::Error for Error { #[cfg(feature = "alloc")] err: ErrorImpl::Message(message.to_string().into()), #[cfg(not(feature = "alloc"))] - err: ErrorImpl::Message, + err: ErrorImpl::Empty, } } } diff --git a/crates/musli-json/Cargo.toml b/crates/musli-json/Cargo.toml index 7c96e2ef4..b5aa6236a 100644 --- a/crates/musli-json/Cargo.toml +++ b/crates/musli-json/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std", "simdutf8", "musli-value", "parse-full"] +default = ["std", "alloc", "simdutf8", "musli-value", "parse-full"] std = ["musli/std", "musli-common/std", "musli-value?/std", "alloc", "lexical/std"] alloc = ["musli/alloc", "musli-common/alloc", "musli-value?/alloc"] test = [] diff --git a/crates/musli-json/src/error.rs b/crates/musli-json/src/error.rs index 11fe9d6c9..30b050ee2 100644 --- a/crates/musli-json/src/error.rs +++ b/crates/musli-json/src/error.rs @@ -19,11 +19,11 @@ impl fmt::Display for Error { } #[derive(Debug)] -pub(crate) enum ErrorImpl { +enum ErrorImpl { #[cfg(feature = "alloc")] Message(Box), #[cfg(not(feature = "alloc"))] - Message, + Empty, } impl fmt::Display for ErrorImpl { @@ -32,7 +32,7 @@ impl fmt::Display for ErrorImpl { #[cfg(feature = "alloc")] ErrorImpl::Message(message) => message.fmt(f), #[cfg(not(feature = "alloc"))] - ErrorImpl::Message => write!(f, "Message error (see diagnostics)"), + ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"), } } } @@ -59,7 +59,7 @@ impl musli_common::context::Error for Error { #[cfg(feature = "alloc")] err: ErrorImpl::Message(message.to_string().into()), #[cfg(not(feature = "alloc"))] - err: ErrorImpl::Message, + err: ErrorImpl::Empty, } } } @@ -80,6 +80,15 @@ impl fmt::Display for ErrorMessage { } } +#[cfg(feature = "std")] +impl std::error::Error for ErrorMessage { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + ErrorMessage::ParseFloat(error) => Some(error), + } + } +} + #[derive(Debug)] #[non_exhaustive] pub(crate) enum IntegerError { diff --git a/crates/musli-json/src/reader/integer.rs b/crates/musli-json/src/reader/integer.rs index abcb4ab5d..11b9ef6f9 100644 --- a/crates/musli-json/src/reader/integer.rs +++ b/crates/musli-json/src/reader/integer.rs @@ -235,7 +235,7 @@ where p.consume_while(cx, is_digit)?; } _ => { - return Err(cx.marked_custom(start, IntegerError::InvalidNumeric)); + return Err(cx.marked_message(start, IntegerError::InvalidNumeric)); } } @@ -293,7 +293,7 @@ where match decode_unsigned_full(cx, p, start)?.compute() { Ok(value) => Ok(value), - Err(error) => Err(cx.marked_custom(start, error)), + Err(error) => Err(cx.marked_message(start, error)), } } @@ -377,7 +377,7 @@ where match decode_signed_base(cx, p)?.compute() { Ok(value) => Ok(value), - Err(error) => Err(cx.marked_custom(start, error)), + Err(error) => Err(cx.marked_message(start, error)), } } @@ -396,7 +396,7 @@ where match decode_signed_full_inner(cx, p)?.compute() { Ok(value) => Ok(value), - Err(error) => Err(cx.marked_custom(start, error)), + Err(error) => Err(cx.marked_message(start, error)), } } @@ -421,7 +421,7 @@ where base } _ => { - return Err(cx.marked_custom(start, IntegerError::InvalidNumeric)); + return Err(cx.marked_message(start, IntegerError::InvalidNumeric)); } }; @@ -463,7 +463,7 @@ where m.value = match m.value.checked_pow10(zeros as u32) { Some(mantissa) => mantissa, None => { - return Err(cx.marked_custom(start, IntegerError::IntegerOverflow)); + return Err(cx.marked_message(start, IntegerError::IntegerOverflow)); } }; } @@ -511,7 +511,7 @@ where match if is_negative { e.negate() } else { e.signed() } { Some(value) => Ok(value), - None => Err(cx.marked_custom(start, IntegerError::IntegerOverflow)), + None => Err(cx.marked_message(start, IntegerError::IntegerOverflow)), } } @@ -524,7 +524,7 @@ where P: ?Sized + Parser<'de>, { let Some(out) = out.checked_mul10() else { - return Err(cx.marked_custom(start, IntegerError::IntegerOverflow)); + return Err(cx.marked_message(start, IntegerError::IntegerOverflow)); }; Ok(out + T::from_byte(p.read_byte(cx)? - b'0')) diff --git a/crates/musli-json/src/reader/string.rs b/crates/musli-json/src/reader/string.rs index 0558ebd6c..22bfe7dd1 100644 --- a/crates/musli-json/src/reader/string.rs +++ b/crates/musli-json/src/reader/string.rs @@ -109,7 +109,7 @@ where cx.advance(1); if !parse_escape(cx, reader, validate, scratch)? { - return Err(cx.marked_custom(open_mark, "Buffer overflow")); + return Err(cx.marked_message(open_mark, "Buffer overflow")); } open = reader.index; @@ -136,7 +136,7 @@ where C: ?Sized + Context, { if musli_common::str::from_utf8(bytes).is_err() { - Err(cx.marked_custom(start, "Invalid unicode string")) + Err(cx.marked_message(start, "Invalid unicode string")) } else { Ok(()) } diff --git a/crates/musli-serde/Cargo.toml b/crates/musli-serde/Cargo.toml index 278db4fc2..63f2992e4 100644 --- a/crates/musli-serde/Cargo.toml +++ b/crates/musli-serde/Cargo.toml @@ -15,8 +15,8 @@ keywords = ["no-std::no-alloc", "no_std", "serde", "serialization"] categories = ["encoding", "encoding", "no-std"] [features] -default = ["std"] -std = ["alloc", "musli/std", "serde/std"] +default = ["std", "alloc"] +std = ["musli/std", "serde/std"] alloc = ["musli/alloc", "serde/alloc"] [dependencies] diff --git a/crates/musli-serde/src/deserializer.rs b/crates/musli-serde/src/deserializer.rs index 2df3f1b84..d146b1683 100644 --- a/crates/musli-serde/src/deserializer.rs +++ b/crates/musli-serde/src/deserializer.rs @@ -468,7 +468,7 @@ where } #[inline] - #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg(feature = "alloc")] fn visit_owned(self, _: &C, value: Vec) -> Result { de::Visitor::visit_byte_buf(self.visitor, value) } @@ -592,7 +592,7 @@ where } #[inline] - #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg(feature = "alloc")] fn visit_owned(self, _: &C, value: String) -> Result { de::Visitor::visit_string(self.visitor, value) } diff --git a/crates/musli-serde/src/lib.rs b/crates/musli-serde/src/lib.rs index 53e45512b..4a2ac657c 100644 --- a/crates/musli-serde/src/lib.rs +++ b/crates/musli-serde/src/lib.rs @@ -45,6 +45,7 @@ mod serializer; use core::cell::RefCell; use core::fmt; +use musli::context::StdError; use musli::{Context, Decoder, Encoder}; use serde::{Deserialize, Serialize}; @@ -84,7 +85,7 @@ where #[inline] fn custom(&self, error: T) -> Self::Error where - T: 'static + Send + Sync + fmt::Display + fmt::Debug, + T: 'static + Send + Sync + StdError, { *self.error.borrow_mut() = Some(self.inner.custom(error)); error::SerdeError::Captured diff --git a/crates/musli-serde/src/serializer.rs b/crates/musli-serde/src/serializer.rs index 31b0fdccb..da446d039 100644 --- a/crates/musli-serde/src/serializer.rs +++ b/crates/musli-serde/src/serializer.rs @@ -1,4 +1,5 @@ -use std::fmt; +#[cfg(any(feature = "std", feature = "alloc"))] +use core::fmt; use musli::en::{ MapEntriesEncoder, SequenceEncoder, StructEncoder, StructFieldEncoder, VariantEncoder, @@ -264,7 +265,19 @@ where where T: fmt::Display, { - let string = value.to_string(); + use core::fmt::Write; + use musli_common::buf::BufString; + + let Some(buf) = self.cx.alloc() else { + return Err(ser::Error::custom("Failed to allocate")); + }; + + let mut string = BufString::new(buf); + + if write!(string, "{value}").is_err() { + return Err(ser::Error::custom("Failed to write to string")); + } + self.serialize_str(&string) } } diff --git a/crates/musli-storage/Cargo.toml b/crates/musli-storage/Cargo.toml index 5d66884cd..3f5972d8b 100644 --- a/crates/musli-storage/Cargo.toml +++ b/crates/musli-storage/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std", "simdutf8"] -std = ["alloc", "musli/std", "musli-common/std"] +default = ["std", "alloc", "simdutf8"] +std = ["musli/std", "musli-common/std"] alloc = ["musli/alloc", "musli-common/alloc"] test = [] simdutf8 = ["musli-common/simdutf8"] diff --git a/crates/musli-storage/src/error.rs b/crates/musli-storage/src/error.rs index 8f3f98fc7..0cbb9b4c7 100644 --- a/crates/musli-storage/src/error.rs +++ b/crates/musli-storage/src/error.rs @@ -23,7 +23,7 @@ enum ErrorImpl { #[cfg(feature = "alloc")] Message(Box), #[cfg(not(feature = "alloc"))] - Message, + Empty, } impl fmt::Display for ErrorImpl { @@ -32,7 +32,7 @@ impl fmt::Display for ErrorImpl { #[cfg(feature = "alloc")] ErrorImpl::Message(message) => message.fmt(f), #[cfg(not(feature = "alloc"))] - ErrorImpl::Message => write!(f, "Message error (see diagnostics)"), + ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"), } } } @@ -59,7 +59,7 @@ impl musli_common::context::Error for Error { #[cfg(feature = "alloc")] err: ErrorImpl::Message(message.to_string().into()), #[cfg(not(feature = "alloc"))] - err: ErrorImpl::Message, + err: ErrorImpl::Empty, } } } diff --git a/crates/musli-value/Cargo.toml b/crates/musli-value/Cargo.toml index 07227a5d6..bb217ce2d 100644 --- a/crates/musli-value/Cargo.toml +++ b/crates/musli-value/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std"] -std = ["alloc", "musli/std", "musli-storage/std", "musli-common/std"] +default = ["std", "alloc"] +std = ["musli/std", "musli-storage/std", "musli-common/std"] alloc = ["musli/alloc", "musli-storage/alloc", "musli-common/alloc"] test = [] diff --git a/crates/musli-value/src/de.rs b/crates/musli-value/src/de.rs index 744d93312..22a4e0d85 100644 --- a/crates/musli-value/src/de.rs +++ b/crates/musli-value/src/de.rs @@ -35,7 +35,7 @@ macro_rules! ensure { $pat => $block, value => { let $hint = value.type_hint(); - return Err($cx.custom(ErrorMessage::$ident $tt)); + return Err($cx.message(ErrorMessage::$ident $tt)); } } }; @@ -94,84 +94,84 @@ impl<'de, C: ?Sized + Context, const F: Options> Decoder<'de, C> for ValueDecode #[inline] fn decode_u8(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::U8, hint), Value::Number(n) => { - u8::from_number(n).map_err(cx.map()) + u8::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_u16(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::U16, hint), Value::Number(n) => { - u16::from_number(n).map_err(cx.map()) + u16::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_u32(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::U32, hint), Value::Number(n) => { - u32::from_number(n).map_err(cx.map()) + u32::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_u64(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::U64, hint), Value::Number(n) => { - u64::from_number(n).map_err(cx.map()) + u64::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_u128(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::U128, hint), Value::Number(n) => { - u128::from_number(n).map_err(cx.map()) + u128::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_i8(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::I8, hint), Value::Number(n) => { - i8::from_number(n).map_err(cx.map()) + i8::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_i16(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::I16, hint), Value::Number(n) => { - i16::from_number(n).map_err(cx.map()) + i16::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_i32(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::I32, hint), Value::Number(n) => { - i32::from_number(n).map_err(cx.map()) + i32::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_i64(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::I64, hint), Value::Number(n) => { - i64::from_number(n).map_err(cx.map()) + i64::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_i128(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::I128, hint), Value::Number(n) => { - i128::from_number(n).map_err(cx.map()) + i128::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_usize(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::Usize, hint), Value::Number(n) => { - usize::from_number(n).map_err(cx.map()) + usize::from_number(n).map_err(cx.map_message()) }) } #[inline] fn decode_isize(self, cx: &C) -> Result { ensure!(self, cx, hint, ExpectedNumber(NumberHint::Isize, hint), Value::Number(n) => { - isize::from_number(n).map_err(cx.map()) + isize::from_number(n).map_err(cx.map_message()) }) } @@ -189,7 +189,7 @@ impl<'de, C: ?Sized + Context, const F: Options> Decoder<'de, C> for ValueDecode #[inline] fn decode_array(self, cx: &C) -> Result<[u8; N], C::Error> { ensure!(self, cx, hint, ExpectedBytes(hint), Value::Bytes(bytes) => { - <[u8; N]>::try_from(bytes.as_slice()).map_err(|_| cx.custom(ErrorMessage::ArrayOutOfBounds)) + <[u8; N]>::try_from(bytes.as_slice()).map_err(|_| cx.message(ErrorMessage::ArrayOutOfBounds)) }) } @@ -359,7 +359,7 @@ impl<'de, C: ?Sized + Context, const F: Options> PackDecoder<'de, C> for IterVal fn decode_next(&mut self, cx: &C) -> Result, C::Error> { match self.iter.next() { Some(value) => Ok(ValueDecoder::new(value)), - None => Err(cx.custom(ErrorMessage::ExpectedPackValue)), + None => Err(cx.message(ErrorMessage::ExpectedPackValue)), } } @@ -467,7 +467,7 @@ impl<'de, C: ?Sized + Context, const F: Options> MapEntriesDecoder<'de, C> cx: &C, ) -> Result, C::Error> { let Some((_, value)) = self.iter.next() else { - return Err(cx.custom(ErrorMessage::ExpectedMapValue)); + return Err(cx.message(ErrorMessage::ExpectedMapValue)); }; Ok(ValueDecoder::new(value)) @@ -554,7 +554,7 @@ impl<'de, C: ?Sized + Context, const F: Options> StructFieldsDecoder<'de, C> cx: &C, ) -> Result, C::Error> { let Some((name, _)) = self.iter.clone().next() else { - return Err(cx.custom(ErrorMessage::ExpectedFieldName)); + return Err(cx.message(ErrorMessage::ExpectedFieldName)); }; Ok(ValueDecoder::new(name)) @@ -566,7 +566,7 @@ impl<'de, C: ?Sized + Context, const F: Options> StructFieldsDecoder<'de, C> cx: &C, ) -> Result, C::Error> { let Some((_, value)) = self.iter.next() else { - return Err(cx.custom(ErrorMessage::ExpectedFieldValue)); + return Err(cx.message(ErrorMessage::ExpectedFieldValue)); }; Ok(ValueDecoder::new(value)) diff --git a/crates/musli-value/src/error.rs b/crates/musli-value/src/error.rs index 8b237996c..f9d5d0247 100644 --- a/crates/musli-value/src/error.rs +++ b/crates/musli-value/src/error.rs @@ -23,11 +23,11 @@ impl fmt::Display for Error { #[allow(missing_docs)] #[derive(Debug)] #[non_exhaustive] -pub(crate) enum ErrorImpl { +enum ErrorImpl { #[cfg(feature = "alloc")] Message(Box), #[cfg(not(feature = "alloc"))] - Message, + Empty, } impl fmt::Display for ErrorImpl { @@ -36,7 +36,7 @@ impl fmt::Display for ErrorImpl { #[cfg(feature = "alloc")] ErrorImpl::Message(message) => message.fmt(f), #[cfg(not(feature = "alloc"))] - ErrorImpl::Message => write!(f, "Message error (see diagnostics)"), + ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"), } } } @@ -63,7 +63,7 @@ impl musli_common::context::Error for Error { #[cfg(feature = "alloc")] err: ErrorImpl::Message(message.to_string().into()), #[cfg(not(feature = "alloc"))] - err: ErrorImpl::Message, + err: ErrorImpl::Empty, } } } diff --git a/crates/musli-wire/Cargo.toml b/crates/musli-wire/Cargo.toml index 3baf1ad90..147e5265e 100644 --- a/crates/musli-wire/Cargo.toml +++ b/crates/musli-wire/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std", "simdutf8"] -std = ["alloc", "musli/std", "musli-common/std", "musli-storage/std"] +default = ["std", "alloc", "simdutf8"] +std = ["musli/std", "musli-common/std", "musli-storage/std"] alloc = ["musli/alloc", "musli-common/alloc", "musli-storage/alloc"] test = [] simdutf8 = ["musli-common/simdutf8"] diff --git a/crates/musli-wire/src/error.rs b/crates/musli-wire/src/error.rs index 031aaa075..bbe10c9a6 100644 --- a/crates/musli-wire/src/error.rs +++ b/crates/musli-wire/src/error.rs @@ -23,7 +23,7 @@ enum ErrorImpl { #[cfg(feature = "alloc")] Message(Box), #[cfg(not(feature = "alloc"))] - Message, + Empty, } impl fmt::Display for ErrorImpl { @@ -32,7 +32,7 @@ impl fmt::Display for ErrorImpl { #[cfg(feature = "alloc")] ErrorImpl::Message(message) => message.fmt(f), #[cfg(not(feature = "alloc"))] - ErrorImpl::Message => write!(f, "Message error (see diagnostics)"), + ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"), } } } @@ -59,7 +59,7 @@ impl musli_common::context::Error for Error { #[cfg(feature = "alloc")] err: ErrorImpl::Message(message.to_string().into()), #[cfg(not(feature = "alloc"))] - err: ErrorImpl::Message, + err: ErrorImpl::Empty, } } } diff --git a/crates/musli-zerocopy/Cargo.toml b/crates/musli-zerocopy/Cargo.toml index 7d3bcde03..84ad45f45 100644 --- a/crates/musli-zerocopy/Cargo.toml +++ b/crates/musli-zerocopy/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization", "zerocopy"] categories = ["encoding", "no-std"] [features] -default = ["std"] -std = ["alloc"] +default = ["std", "alloc"] +std = [] alloc = [] [dependencies] diff --git a/crates/musli/Cargo.toml b/crates/musli/Cargo.toml index 7a5ec0e45..a3dc76c76 100644 --- a/crates/musli/Cargo.toml +++ b/crates/musli/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["no-std::no-alloc", "no_std", "serialization"] categories = ["encoding", "no-std"] [features] -default = ["std"] -std = ["alloc"] +default = ["std", "alloc"] +std = [] alloc = [] [dependencies] diff --git a/crates/musli/src/context.rs b/crates/musli/src/context.rs index 894350ba5..5f438aec5 100644 --- a/crates/musli/src/context.rs +++ b/crates/musli/src/context.rs @@ -4,6 +4,16 @@ use core::fmt; use crate::{Buf, Decode, Decoder}; +#[cfg(feature = "std")] +pub use std::error::Error as StdError; + +/// Standard error trait used when the `std` feature is not enabled. +#[cfg(not(feature = "std"))] +pub trait StdError: fmt::Debug + fmt::Display {} + +#[cfg(not(feature = "std"))] +impl StdError for T where T: fmt::Debug + fmt::Display {} + /// Provides ergonomic access to the serialization context. /// /// This is used to among other things report diagnostics. @@ -31,10 +41,10 @@ pub trait Context { /// Allocate a buffer. fn alloc(&self) -> Option>; - /// Generate a map function which maps an error using the `report` function. + /// Generate a map function which maps an error using the `custom` function. fn map(&self) -> impl FnOnce(T) -> Self::Error + '_ where - T: 'static + Send + Sync + fmt::Display + fmt::Debug, + T: 'static + Send + Sync + StdError, { move |error| self.custom(error) } @@ -44,7 +54,15 @@ pub trait Context { /// reporting error-like things out from the context. fn custom(&self, error: T) -> Self::Error where - T: 'static + Send + Sync + fmt::Display + fmt::Debug; + T: 'static + Send + Sync + StdError; + + /// Generate a map function which maps an error using the `message` function. + fn map_message(&self) -> impl FnOnce(T) -> Self::Error + '_ + where + T: fmt::Display, + { + move |error| self.message(error) + } /// Report a message as an error. /// @@ -73,7 +91,7 @@ pub trait Context { #[inline(always)] fn marked_custom(&self, mark: Self::Mark, message: T) -> Self::Error where - T: 'static + Send + Sync + fmt::Display + fmt::Debug, + T: 'static + Send + Sync + StdError, { self.custom(message) } diff --git a/crates/musli/src/internal/size_hint.rs b/crates/musli/src/internal/size_hint.rs index 91286b676..d8b97809c 100644 --- a/crates/musli/src/internal/size_hint.rs +++ b/crates/musli/src/internal/size_hint.rs @@ -1,7 +1,7 @@ -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(feature = "alloc")] use crate::de::SizeHint; -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(feature = "alloc")] #[inline] pub(crate) fn cautious(hint: S) -> usize where diff --git a/crates/tests/Cargo.toml b/crates/tests/Cargo.toml index 5aeac5c57..303a9a36b 100644 --- a/crates/tests/Cargo.toml +++ b/crates/tests/Cargo.toml @@ -10,11 +10,11 @@ license = "MIT OR Apache-2.0" publish = false [features] -default = ["std"] +default = ["std", "alloc"] extra = ["rkyv", "dlhn", "serde_cbor"] full = ["rmp-serde", "bincode", "postcard", "musli-json", "serde_json", "bitcode", "bitcode-derive"] text = ["musli-json", "serde_json"] -std = ["alloc", "musli?/std", "musli-wire?/std", "musli-storage?/std", "musli-json?/std", "musli-zerocopy?/std", "rand/std", "serde_json?/std", "rkyv?/std", "serde?/std"] +std = ["musli?/std", "musli-wire?/std", "musli-storage?/std", "musli-json?/std", "musli-zerocopy?/std", "rand/std", "serde_json?/std", "rkyv?/std", "serde?/std"] alloc = ["musli?/alloc", "musli-wire?/alloc", "musli-storage?/alloc", "musli-json?/alloc", "musli-zerocopy?/alloc"] simdutf8 = ["musli-wire?/simdutf8", "musli-storage?/simdutf8", "musli-descriptive?/simdutf8", "musli-json?/simdutf8", "bitcode?/simdutf8"] parse-full = ["musli-json?/parse-full"]