diff options
-rw-r--r-- | CHANGELOG.md | 10 | ||||
-rw-r--r-- | bzipper/Cargo.toml | 4 | ||||
-rw-r--r-- | bzipper/src/decode/mod.rs | 358 | ||||
-rw-r--r-- | bzipper/src/decode/tuple.rs | 324 | ||||
-rw-r--r-- | bzipper/src/encode/mod.rs | 343 | ||||
-rw-r--r-- | bzipper/src/encode/tuple.rs | 302 | ||||
-rw-r--r-- | bzipper/src/i_stream/mod.rs | 2 | ||||
-rw-r--r-- | bzipper/src/o_stream/mod.rs | 2 | ||||
-rw-r--r-- | bzipper/src/sized_encode/mod.rs | 186 | ||||
-rw-r--r-- | bzipper/src/sized_encode/tuple.rs | 253 | ||||
-rw-r--r-- | bzipper_benchmarks/Cargo.toml | 4 | ||||
-rw-r--r-- | bzipper_macros/Cargo.toml | 2 | ||||
-rw-r--r-- | bzipper_macros/src/impls/encode_enum.rs | 2 | ||||
-rw-r--r-- | bzipper_macros/src/lib.rs | 8 |
14 files changed, 753 insertions, 1047 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ceeca7..0c2d328 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ This is the changelog of bzipper. See `README.md` for more information. +## 0.9.0 + +* Implement `Encode` and `Decode` for `LinkedList`, `HashMap`, `Cow`, `PhantomPinned`, `LazyCell`, `LazyLock` +* Add missing `Decode` implementation for `Box` +* Update inline rules +* Implement traits for tuples using macros +* Implement `SizedEncode` for `PhantomPinned`, `Cow`, `LazyCell`, `LazyLock`, `&_`, `&mut _` +* Implement `Encode` for `&_` and `&mut _` +* Update docs + ## 0.8.1 * Update package metadata diff --git a/bzipper/Cargo.toml b/bzipper/Cargo.toml index 6f8609b..3e5f303 100644 --- a/bzipper/Cargo.toml +++ b/bzipper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bzipper" -version = "0.8.1" +version = "0.9.0" edition = "2021" rust-version = "1.83" documentation = "https://docs.rs/bzipper/" @@ -24,7 +24,7 @@ alloc = [] std = [] [dependencies] -bzipper_macros = { path = "../bzipper_macros", version = "0.8.1" } +bzipper_macros = { path = "../bzipper_macros", version = "0.9.0" } [lints] workspace = true diff --git a/bzipper/src/decode/mod.rs b/bzipper/src/decode/mod.rs index 6a0c35d..1fbdaa2 100644 --- a/bzipper/src/decode/mod.rs +++ b/bzipper/src/decode/mod.rs @@ -26,7 +26,8 @@ use crate::{IStream, SizedEncode}; use crate::error::{DecodeError, Utf8Error}; use core::convert::Infallible; -use core::marker::PhantomData; +use core::hash::Hash; +use core::marker::{PhantomData, PhantomPinned}; use core::mem::MaybeUninit; use core::net::{ IpAddr, @@ -48,6 +49,15 @@ use core::ops::{ }; #[cfg(feature = "alloc")] +use alloc::borrow::{Cow, ToOwned}; + +#[cfg(feature = "alloc")] +use std::boxed::Box; + +#[cfg(feature = "alloc")] +use std::collections::LinkedList; + +#[cfg(feature = "alloc")] use alloc::string::String; #[cfg(feature = "alloc")] @@ -60,9 +70,13 @@ use alloc::rc::Rc; use alloc::sync::Arc; #[cfg(feature = "std")] -use std::sync::{Mutex, RwLock}; +use std::collections::HashMap; + +#[cfg(feature = "std")] +use std::hash::BuildHasher; -mod tuple; +#[cfg(feature = "std")] +use std::sync::{Mutex, RwLock}; // Should we require `Encode` for `Decode`? @@ -76,53 +90,17 @@ pub trait Decode: Sized { fn decode(stream: &mut IStream) -> Result<Self, DecodeError>; } -macro_rules! impl_numeric { - ($ty:ty$(,)?) => { - impl ::bzipper::Decode for $ty { - #[inline] - fn decode(stream: &mut IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { - let data = stream - .read(Self::MAX_ENCODED_SIZE) - .try_into() - .expect(concat!("mismatch between `", stringify!($ty), "::MAX_ENCODED_SIZE` and buffer needed by `", stringify!($ty), "::from_be_bytes`")); - - let this = Self::from_be_bytes(data); - Ok(this) - } - } - }; -} - -macro_rules! impl_non_zero { - ($ty:ty$(,)?) => { - impl ::bzipper::Decode for NonZero<$ty> { - #[inline] - fn decode(stream: &mut IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { - let value = <$ty as ::bzipper::Decode>::decode(stream)?; - - let this = NonZero::new(value) - .ok_or(::bzipper::error::DecodeError::NullInteger)?; - - Ok(this) - } - } - }; -} +/// Implemented for tuples with up to twelve members. +#[cfg_attr(doc, doc(fake_variadic))] +impl<T> Decode for (T, ) +where + T: Decode, { + #[inline(always)] + fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { + let value = (Decode::decode(stream)?, ); -macro_rules! impl_atomic { - { - width: $width:literal, - ty: $ty:ty$(,)? - } => { - #[cfg(target_has_atomic = $width)] - #[cfg_attr(doc, doc(cfg(target_has_atomic = $width)))] - impl ::bzipper::Decode for $ty { - #[inline(always)] - fn decode(stream: &mut ::bzipper::IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { - Ok(Self::new(::bzipper::Decode::decode(stream)?)) - } - } - }; + Ok(value) + } } impl<T: Decode, const N: usize> Decode for [T; N] { @@ -196,6 +174,18 @@ impl<T: Decode> Decode for Bound<T> { } } +#[cfg(feature = "alloc")] +#[cfg_attr(doc, doc(cfg(feature = "alloc")))] +impl<T: Decode> Decode for Box<T> { + #[inline(always)] + fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { + let value = T::decode(stream)?; + + let this = Self::new(value); + Ok(this) + } +} + impl Decode for char { #[inline] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { @@ -209,6 +199,43 @@ impl Decode for char { } } +#[cfg(feature = "alloc")] +#[cfg_attr(doc, doc(cfg(feature = "alloc")))] +impl<T: ToOwned<Owned = U>, U: Decode> Decode for Cow<'_, T> { + #[inline(always)] + fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { + let value = U::decode(stream)?; + + let this = Self::Owned(value); + Ok(this) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(doc, doc(cfg(feature = "std")))] +impl<K, V, S> Decode for HashMap<K, V, S> +where + K: Decode + Eq + Hash, + V: Decode, + S: BuildHasher + Default, + { + #[inline] + fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { + let len = Decode::decode(stream)?; + + let mut this = Self::with_capacity_and_hasher(len, Default::default()); + + for _ in 0x0..len { + let key = Decode::decode(stream)?; + let value = Decode::decode(stream)?; + + this.insert(key, value); + } + + Ok(this) + } +} + impl Decode for Infallible { #[expect(clippy::panic_in_result_fn)] #[inline(always)] @@ -220,13 +247,11 @@ impl Decode for Infallible { impl Decode for IpAddr { #[inline] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - use IpAddr::*; - let discriminant = u8::decode(stream)?; let this = match discriminant { - 0x4 => V4(Decode::decode(stream)?), - 0x6 => V6(Decode::decode(stream)?), + 0x4 => Self::V4(Decode::decode(stream)?), + 0x6 => Self::V6(Decode::decode(stream)?), _ => return Err(DecodeError::InvalidDiscriminant(discriminant.into())) }; @@ -254,13 +279,32 @@ impl Decode for Ipv6Addr { } impl Decode for isize { - #[inline] + #[inline(always)] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { let value = i16::decode(stream)?; Ok(value as Self) } } +#[cfg(feature = "alloc")] +#[cfg_attr(doc, doc(cfg(feature = "alloc")))] +impl<T: Decode> Decode for LinkedList<T> { + #[inline] + fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { + let len = usize::decode(stream)?; + + let mut this = Self::new(); + + for _ in 0x0..len { + let value = T::decode(stream)?; + + this.push_back(value); + } + + Ok(this) + } +} + #[cfg(feature = "std")] #[cfg_attr(doc, doc(cfg(feature = "std")))] impl<T: Decode> Decode for Mutex<T> { @@ -271,7 +315,7 @@ impl<T: Decode> Decode for Mutex<T> { } impl<T: Decode> Decode for Option<T> { - #[expect(clippy::if_then_some_else_none)] + #[expect(clippy::if_then_some_else_none)] // ??? #[inline] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { let sign = bool::decode(stream)?; @@ -293,6 +337,13 @@ impl<T> Decode for PhantomData<T> { } } +impl Decode for PhantomPinned { + #[inline(always)] + fn decode(_stream: &mut IStream) -> Result<Self, DecodeError> { + Ok(Self) + } +} + impl<T: Decode> Decode for Range<T> { #[inline(always)] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { @@ -388,15 +439,13 @@ impl<T: Decode> Decode for Saturating<T> { } impl Decode for SocketAddr { - #[inline(always)] + #[inline] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - use SocketAddr::*; - let discriminant = u8::decode(stream)?; let this = match discriminant { - 0x4 => V4(Decode::decode(stream)?), - 0x6 => V6(Decode::decode(stream)?), + 0x4 => Self::V4(Decode::decode(stream)?), + 0x6 => Self::V6(Decode::decode(stream)?), _ => return Err(DecodeError::InvalidDiscriminant(discriminant.into())) }; @@ -454,7 +503,7 @@ impl Decode for () { } impl Decode for usize { - #[inline] + #[inline(always)] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { let value = u16::decode(stream)?; Ok(value as Self) @@ -464,13 +513,13 @@ impl Decode for usize { #[cfg(feature = "alloc")] #[cfg_attr(doc, doc(cfg(feature = "alloc")))] impl<T: Decode> Decode for Vec<T> { - #[inline(always)] + #[inline] fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { let len = Decode::decode(stream)?; - let mut v = Self::with_capacity(len); + let mut this = Self::with_capacity(len); - let buf = v.as_mut_ptr(); + let buf = this.as_mut_ptr(); for i in 0x0..len { let value = Decode::decode(stream)?; @@ -480,9 +529,9 @@ impl<T: Decode> Decode for Vec<T> { } // SAFETY: We have initialised the buffer. - unsafe { v.set_len(len); } + unsafe { this.set_len(len); } - Ok(v) + Ok(this) } } @@ -493,6 +542,73 @@ impl<T: Decode> Decode for Wrapping<T> { } } +macro_rules! impl_numeric { + ($ty:ty$(,)?) => { + impl ::bzipper::Decode for $ty { + #[inline] + fn decode(stream: &mut IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { + let data = stream + .read(Self::MAX_ENCODED_SIZE) + .try_into() + .expect(concat!("mismatch between `", stringify!($ty), "::MAX_ENCODED_SIZE` and buffer needed by `", stringify!($ty), "::from_be_bytes`")); + + let this = Self::from_be_bytes(data); + Ok(this) + } + } + }; +} + +macro_rules! impl_tuple { + { + $($tys:ident),+$(,)? + } => { + #[doc(hidden)] + impl<$($tys: ::bzipper::Decode, )*> ::bzipper::Decode for ($($tys, )*) { + #[inline(always)] + fn decode(stream: &mut ::bzipper::IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { + let this = ( + $( <$tys as ::bzipper::Decode>::decode(stream)?, )* + ); + + Ok(this) + } + } + }; +} + +macro_rules! impl_non_zero { + ($ty:ty$(,)?) => { + impl ::bzipper::Decode for NonZero<$ty> { + #[inline] + fn decode(stream: &mut IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { + let value = <$ty as ::bzipper::Decode>::decode(stream)?; + + let this = NonZero::new(value) + .ok_or(::bzipper::error::DecodeError::NullInteger)?; + + Ok(this) + } + } + }; +} + +macro_rules! impl_atomic { + { + width: $width:literal, + ty: $ty:ty$(,)? + } => { + #[cfg(target_has_atomic = $width)] + #[cfg_attr(doc, doc(cfg(target_has_atomic = $width)))] + impl ::bzipper::Decode for $ty { + #[inline(always)] + fn decode(stream: &mut ::bzipper::IStream) -> ::core::result::Result<Self, ::bzipper::error::DecodeError> { + Ok(Self::new(::bzipper::Decode::decode(stream)?)) + } + } + }; +} + //impl_numeric!(f128); //impl_numeric!(f16); impl_numeric!(f32); @@ -508,6 +624,116 @@ impl_numeric!(u32); impl_numeric!(u64); impl_numeric!(u8); +impl_tuple! { + T0, + T1, +} + +impl_tuple! { + T0, + T1, + T2, +} + +impl_tuple! { + T0, + T1, + T2, + T3, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, +} + impl_non_zero!(i128); impl_non_zero!(i16); impl_non_zero!(i32); diff --git a/bzipper/src/decode/tuple.rs b/bzipper/src/decode/tuple.rs deleted file mode 100644 index eb66db7..0000000 --- a/bzipper/src/decode/tuple.rs +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2024 Gabriel Bjørnager Jensen. -// -// This file is part of bZipper. -// -// bZipper is free software: you can redistribute -// it and/or modify it under the terms of the GNU -// Lesser General Public License as published by -// the Free Software Foundation, either version 3 -// of the License, or (at your option) any later -// version. -// -// bZipper is distributed in the hope that it will -// be useful, but WITHOUT ANY WARRANTY; without -// even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Less- -// er General Public License along with bZipper. If -// not, see <https://www.gnu.org/licenses/>. - -use crate::{IStream, Decode}; -use crate::error::DecodeError; - -/// Implemented for tuples with up to twelve members. -#[cfg_attr(doc, doc(fake_variadic))] -impl<T> Decode for (T, ) -where - T: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1> Decode for (T0, T1) -where - T0: Decode, - T1: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2> Decode for (T0, T1, T2) -where - T0: Decode, - T1: Decode, - T2: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3> Decode for (T0, T1, T2, T3) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4> Decode for (T0, T1, T2, T3, T4) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5> Decode for (T0, T1, T2, T3, T4, T5) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6> Decode for (T0, T1, T2, T3, T4, T5, T6) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, - T6: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7> Decode for (T0, T1, T2, T3, T4, T5, T6, T7) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, - T6: Decode, - T7: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> Decode for (T0, T1, T2, T3, T4, T5, T6, T7, T8) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, - T6: Decode, - T7: Decode, - T8: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> Decode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, - T6: Decode, - T7: Decode, - T8: Decode, - T9: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Decode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, - T6: Decode, - T7: Decode, - T8: Decode, - T9: Decode, - T10: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Decode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -where - T0: Decode, - T1: Decode, - T2: Decode, - T3: Decode, - T4: Decode, - T5: Decode, - T6: Decode, - T7: Decode, - T8: Decode, - T9: Decode, - T10: Decode, - T11: Decode, { - #[inline(always)] - fn decode(stream: &mut IStream) -> Result<Self, DecodeError> { - let value = ( - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - Decode::decode(stream)?, - ); - - Ok(value) - } -} diff --git a/bzipper/src/encode/mod.rs b/bzipper/src/encode/mod.rs index faa910f..24a377d 100644 --- a/bzipper/src/encode/mod.rs +++ b/bzipper/src/encode/mod.rs @@ -25,10 +25,11 @@ mod test; use crate::OStream; use crate::error::EncodeError; -use core::cell::RefCell; +use core::cell::{LazyCell, RefCell}; use core::convert::Infallible; +use core::hash::BuildHasher; use core::hint::unreachable_unchecked; -use core::marker::PhantomData; +use core::marker::{PhantomData, PhantomPinned}; use core::net::{ IpAddr, Ipv4Addr, @@ -49,9 +50,15 @@ use core::ops::{ }; #[cfg(feature = "alloc")] +use alloc::borrow::{Cow, ToOwned}; + +#[cfg(feature = "alloc")] use alloc::boxed::Box; #[cfg(feature = "alloc")] +use alloc::collections::LinkedList; + +#[cfg(feature = "alloc")] use alloc::string::String; #[cfg(feature = "alloc")] @@ -64,9 +71,10 @@ use alloc::rc::Rc; use alloc::sync::Arc; #[cfg(feature = "std")] -use std::sync::{Mutex, RwLock}; +use std::collections::HashMap; -mod tuple; +#[cfg(feature = "std")] +use std::sync::{LazyLock, Mutex, RwLock}; /// Denotes a type capable of being encoded. /// @@ -116,54 +124,34 @@ pub trait Encode { fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError>; } -macro_rules! impl_numeric { - ($ty:ty$(,)?) => { - impl ::bzipper::Encode for $ty { - #[inline] - fn encode(&self, stream: &mut OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { - stream.write(&self.to_be_bytes()); - - Ok(()) - } - } - }; +impl<T: Encode> Encode for &T { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + T::encode(self, stream) + } } -macro_rules! impl_non_zero { - ($ty:ty$(,)?) => { - impl ::bzipper::Encode for ::core::num::NonZero<$ty> { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { - self.get().encode(stream) - } - } - }; +impl<T: Encode> Encode for &mut T { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + T::encode(self, stream) + } } -macro_rules! impl_atomic { - { - width: $width:literal, - ty: $ty:ty, - atomic_ty: $atomic_ty:ty$(,)? - } => { - /// This implementation uses the same format as the atomic's primitive counterpart. - /// The atomic object itself is read with the [`Relaxed`](core::sync::atomic::Ordering) ordering scheme. - #[cfg(target_has_atomic = $width)] - #[cfg_attr(doc, doc(cfg(target_has_atomic = $width)))] - impl ::bzipper::Encode for $atomic_ty { - #[inline(always)] - fn encode(&self, stream: &mut ::bzipper::OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { - self.load(::std::sync::atomic::Ordering::Relaxed).encode(stream) - } - } - }; +/// Implemented for tuples with up to twelve members. +#[cfg_attr(doc, doc(fake_variadic))] +impl<T: Encode> Encode for (T, ) { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + self.0.encode(stream) + } } impl<T: Encode, const N: usize> Encode for [T; N] { #[inline(always)] fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - for v in self { - v.encode(stream)?; + for value in self { + value.encode(stream)?; } Ok(()) @@ -175,8 +163,8 @@ impl<T: Encode> Encode for [T] { fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { self.len().encode(stream)?; - for v in self { - v.encode(stream)?; + for value in self { + value.encode(stream)?; } Ok(()) @@ -202,20 +190,18 @@ impl Encode for bool { impl<T: Encode> Encode for Bound<T> { #[inline(always)] fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - use Bound::*; - match *self { - Included(ref bound) => { + Self::Included(ref bound) => { 0x0u8.encode(stream)?; bound.encode(stream)?; } - Excluded(ref bound) => { + Self::Excluded(ref bound) => { 0x1u8.encode(stream)?; bound.encode(stream)?; } - Unbounded => { + Self::Unbounded => { 0x2u8.encode(stream)?; } } @@ -240,6 +226,34 @@ impl Encode for char { } } +#[cfg(feature = "alloc")] +#[cfg_attr(doc, doc(cfg(feature = "alloc")))] +impl<T: Encode + ToOwned> Encode for Cow<'_, T> { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + T::encode(self, stream) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(doc, doc(cfg(feature = "std")))] +impl<K, V, S> Encode for HashMap<K, V, S> +where + K: Encode, + V: Encode, + S: BuildHasher, + { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + for (key, value) in self { + key.encode(stream)?; + value.encode(stream)?; + } + + Ok(()) + } +} + // Especially useful for `Result<T, Infallible>`. // **If** that is even needed, of course. impl Encode for Infallible { @@ -256,17 +270,15 @@ impl Encode for Infallible { impl Encode for IpAddr { #[inline(always)] fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - use IpAddr::*; - // The discriminant here is the IP version. match *self { - V4(ref addr) => { + Self::V4(ref addr) => { 0x4u8.encode(stream)?; addr.encode(stream)?; } - V6(ref addr) => { + Self::V6(ref addr) => { 0x6u8.encode(stream)?; addr.encode(stream)?; } @@ -306,6 +318,35 @@ impl Encode for isize { } } +impl<T: Encode> Encode for LazyCell<T> { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + T::encode(self, stream) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(doc, doc(cfg(feature = "std")))] +impl<T: Encode> Encode for LazyLock<T> { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + T::encode(self, stream) + } +} + +#[cfg(feature = "alloc")] +#[cfg_attr(doc, doc(cfg(feature = "alloc")))] +impl<T: Encode> Encode for LinkedList<T> { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { + for value in self { + value.encode(stream)?; + } + + Ok(()) + } +} + #[cfg(feature = "std")] #[cfg_attr(doc, doc(cfg(feature = "std")))] impl<T: Encode> Encode for Mutex<T> { @@ -313,7 +354,7 @@ impl<T: Encode> Encode for Mutex<T> { fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { self .lock() - .or_else(|e| Ok(e.into_inner()))? + .unwrap_or_else(std::sync::PoisonError::into_inner) .encode(stream) } } @@ -323,10 +364,6 @@ impl<T: Encode> Encode for Mutex<T> { /// The contained value is encoded proceeding the sign. impl<T: Encode> Encode for Option<T> { fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - // The first element is of type `bool` and is - // called the "sign." It signifies whether there is - // a following element or not. - match *self { None => false.encode(stream)?, @@ -347,6 +384,13 @@ impl<T> Encode for PhantomData<T> { } } +impl Encode for PhantomPinned { + #[inline(always)] + fn encode(&self, _stream: &mut OStream) -> Result<(), EncodeError> { + Ok(()) + } +} + impl<T: Encode> Encode for Range<T> { #[inline(always)] fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { @@ -463,19 +507,17 @@ impl<T: Encode> Encode for Saturating<T> { /// This implementation encoded as discriminant denoting the IP version of the address (i.e. `4` for IPv4 and `6` for IPv6). /// This is then followed by the respective address' own encoding (either [`SocketAddrV4`] or [`SocketAddrV6`]). impl Encode for SocketAddr { - #[inline(always)] + #[inline] fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - use SocketAddr::*; - // The discriminant here is the IP version. match *self { - V4(ref addr) => { + Self::V4(ref addr) => { 0x4u8.encode(stream)?; addr.encode(stream)?; } - V6(ref addr) => { + Self::V6(ref addr) => { 0x6u8.encode(stream)?; addr.encode(stream)?; } @@ -564,6 +606,69 @@ impl<T: Encode> Encode for Wrapping<T> { } } +macro_rules! impl_numeric { + ($ty:ty$(,)?) => { + impl ::bzipper::Encode for $ty { + #[inline] + fn encode(&self, stream: &mut OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { + stream.write(&self.to_be_bytes()); + + Ok(()) + } + } + }; +} + +macro_rules! impl_tuple { + { + $($captures:ident: $tys:ident),+$(,)? + } => { + #[doc(hidden)] + impl<$($tys: ::bzipper::Encode, )*> ::bzipper::Encode for ($($tys, )*) { + #[inline(always)] + fn encode(&self, stream: &mut ::bzipper::OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { + let ($(ref $captures, )*) = *self; + + $( + $captures.encode(stream)?; + )* + + Ok(()) + } + } + }; +} + +macro_rules! impl_non_zero { + ($ty:ty$(,)?) => { + impl ::bzipper::Encode for ::core::num::NonZero<$ty> { + #[inline(always)] + fn encode(&self, stream: &mut OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { + self.get().encode(stream) + } + } + }; +} + +macro_rules! impl_atomic { + { + width: $width:literal, + ty: $ty:ty, + atomic_ty: $atomic_ty:ty$(,)? + } => { + /// This implementation uses the same format as the atomic's primitive counterpart. + /// The atomic object itself is read with the [`Relaxed`](core::sync::atomic::Ordering) ordering scheme. + #[cfg(target_has_atomic = $width)] + #[cfg_attr(doc, doc(cfg(target_has_atomic = $width)))] + impl ::bzipper::Encode for $atomic_ty { + #[inline(always)] + fn encode(&self, stream: &mut ::bzipper::OStream) -> ::core::result::Result<(), ::bzipper::error::EncodeError> { + self.load(::std::sync::atomic::Ordering::Relaxed).encode(stream) + } + } + }; +} + //impl_numeric!(f128); //impl_numeric!(f16); impl_numeric!(f32); @@ -579,6 +684,116 @@ impl_numeric!(u32); impl_numeric!(u64); impl_numeric!(u8); +impl_tuple! { + value0: T0, + value1: T1, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, + value6: T6, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, + value6: T6, + value7: T7, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, + value6: T6, + value7: T7, + value8: T8, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, + value6: T6, + value7: T7, + value8: T8, + value9: T9, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, + value6: T6, + value7: T7, + value8: T8, + value9: T9, + value10: T10, +} + +impl_tuple! { + value0: T0, + value1: T1, + value2: T2, + value3: T3, + value4: T4, + value5: T5, + value6: T6, + value7: T7, + value8: T8, + value9: T9, + value10: T10, + value11: T11, +} + impl_non_zero!(i128); impl_non_zero!(i16); impl_non_zero!(i32); diff --git a/bzipper/src/encode/tuple.rs b/bzipper/src/encode/tuple.rs deleted file mode 100644 index 66cdf24..0000000 --- a/bzipper/src/encode/tuple.rs +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright 2024 Gabriel Bjørnager Jensen. -// -// This file is part of bZipper. -// -// bZipper is free software: you can redistribute -// it and/or modify it under the terms of the GNU -// Lesser General Public License as published by -// the Free Software Foundation, either version 3 -// of the License, or (at your option) any later -// version. -// -// bZipper is distributed in the hope that it will -// be useful, but WITHOUT ANY WARRANTY; without -// even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Less- -// er General Public License along with bZipper. If -// not, see <https://www.gnu.org/licenses/>. - -use crate::{Encode, OStream}; -use crate::error::EncodeError; - -/// Implemented for tuples with up to twelve members. -#[cfg_attr(doc, doc(fake_variadic))] -impl<T> Encode for (T, ) -where - T: Encode, { - - #[doc(hidden)] - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1> Encode for (T0, T1) -where - T0: Encode, - T1: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2> Encode for (T0, T1, T2) -where - T0: Encode, - T1: Encode, - T2: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3> Encode for (T0, T1, T2, T3) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4> Encode for (T0, T1, T2, T3, T4) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5> Encode for (T0, T1, T2, T3, T4, T5) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6> Encode for (T0, T1, T2, T3, T4, T5, T6) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, - T6: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - self.6.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7> Encode for (T0, T1, T2, T3, T4, T5, T6, T7) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, - T6: Encode, - T7: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - self.6.encode(stream)?; - self.7.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> Encode for (T0, T1, T2, T3, T4, T5, T6, T7, T8) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, - T6: Encode, - T7: Encode, - T8: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - self.6.encode(stream)?; - self.7.encode(stream)?; - self.8.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> Encode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, - T6: Encode, - T7: Encode, - T8: Encode, - T9: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - self.6.encode(stream)?; - self.7.encode(stream)?; - self.8.encode(stream)?; - self.9.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Encode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, - T6: Encode, - T7: Encode, - T8: Encode, - T9: Encode, - T10: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - self.6.encode(stream)?; - self.7.encode(stream)?; - self.8.encode(stream)?; - self.9.encode(stream)?; - self.10.encode(stream)?; - - Ok(()) - } -} - -#[doc(hidden)] -impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Encode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -where - T0: Encode, - T1: Encode, - T2: Encode, - T3: Encode, - T4: Encode, - T5: Encode, - T6: Encode, - T7: Encode, - T8: Encode, - T9: Encode, - T10: Encode, - T11: Encode, { - #[inline(always)] - fn encode(&self, stream: &mut OStream) -> Result<(), EncodeError> { - self.0.encode(stream)?; - self.1.encode(stream)?; - self.2.encode(stream)?; - self.3.encode(stream)?; - self.4.encode(stream)?; - self.5.encode(stream)?; - self.6.encode(stream)?; - self.7.encode(stream)?; - self.8.encode(stream)?; - self.9.encode(stream)?; - self.10.encode(stream)?; - self.11.encode(stream)?; - - Ok(()) - } -} diff --git a/bzipper/src/i_stream/mod.rs b/bzipper/src/i_stream/mod.rs index 30cb16f..ced337d 100644 --- a/bzipper/src/i_stream/mod.rs +++ b/bzipper/src/i_stream/mod.rs @@ -21,7 +21,7 @@ use core::slice; -/// Byte stream suitable for decoding. +/// Byte stream suitable for input. pub struct IStream<'a> { buf: &'a [u8], pos: usize, diff --git a/bzipper/src/o_stream/mod.rs b/bzipper/src/o_stream/mod.rs index c38c079..cf63bcf 100644 --- a/bzipper/src/o_stream/mod.rs +++ b/bzipper/src/o_stream/mod.rs @@ -21,7 +21,7 @@ use core::ptr::copy_nonoverlapping; -/// Byte stream suitable for encoding. +/// Byte stream suitable for output. pub struct OStream<'a> { buf: &'a mut [u8], pos: usize, diff --git a/bzipper/src/sized_encode/mod.rs b/bzipper/src/sized_encode/mod.rs index 3a52397..bc0dc6e 100644 --- a/bzipper/src/sized_encode/mod.rs +++ b/bzipper/src/sized_encode/mod.rs @@ -55,8 +55,6 @@ use std::rc::Rc; #[cfg(feature = "std")] use std::sync::{Arc, Mutex, RwLock}; -mod tuple; - /// Denotes a size-constrained, encodable type. /// /// When using [`Encode`], the size of the resulting encoding cannot always be known beforehand. @@ -73,34 +71,19 @@ pub unsafe trait SizedEncode: Encode + Sized { const MAX_ENCODED_SIZE: usize; } -macro_rules! impl_numeric { - ($ty:ty$(,)?) => { - unsafe impl ::bzipper::SizedEncode for $ty { - const MAX_ENCODED_SIZE: usize = size_of::<$ty>(); - } - }; +unsafe impl<T: SizedEncode> SizedEncode for &T { + const MAX_ENCODED_SIZE: usize = T::MAX_ENCODED_SIZE; } -macro_rules! impl_non_zero { - ($ty:ty$(,)?) => { - unsafe impl ::bzipper::SizedEncode for ::core::num::NonZero<$ty> { - const MAX_ENCODED_SIZE: usize = <$ty as ::bzipper::SizedEncode>::MAX_ENCODED_SIZE; - } - }; +unsafe impl<T: SizedEncode> SizedEncode for &mut T { + const MAX_ENCODED_SIZE: usize = T::MAX_ENCODED_SIZE; } -macro_rules! impl_atomic { - { - width: $width:literal, - ty: $ty:ty, - atomic_ty: $atomic_ty:ty$(,)? - } => { - #[cfg(target_has_atomic = $width)] - #[cfg_attr(doc, doc(cfg(target_has_atomic = $width)))] - unsafe impl ::bzipper::SizedEncode for $atomic_ty { - const MAX_ENCODED_SIZE: usize = <$ty as ::bzipper::SizedEncode>::MAX_ENCODED_SIZE; - } - }; +/// Implemented for tuples with up to twelve members. +#[cfg_attr(doc, doc(fake_variadic))] +unsafe impl<T: SizedEncode> SizedEncode for (T, ) { + #[doc(hidden)] + const MAX_ENCODED_SIZE: usize = T::MAX_ENCODED_SIZE; } unsafe impl<T: SizedEncode, const N: usize> SizedEncode for [T; N] { @@ -247,6 +230,47 @@ unsafe impl<T: SizedEncode> SizedEncode for Wrapping<T> { const MAX_ENCODED_SIZE: usize = T::MAX_ENCODED_SIZE; } +macro_rules! impl_numeric { + ($ty:ty$(,)?) => { + unsafe impl ::bzipper::SizedEncode for $ty { + const MAX_ENCODED_SIZE: usize = size_of::<$ty>(); + } + }; +} + +macro_rules! impl_tuple { + { + $($tys:ident),+$(,)? + } => { + #[doc(hidden)] + unsafe impl<$($tys: ::bzipper::SizedEncode, )*> ::bzipper::SizedEncode for ($($tys, )*) { + const MAX_ENCODED_SIZE: usize = 0x0 $(+ <$tys as ::bzipper::SizedEncode>::MAX_ENCODED_SIZE)*; + } + }; +} + +macro_rules! impl_non_zero { + ($ty:ty$(,)?) => { + unsafe impl ::bzipper::SizedEncode for ::core::num::NonZero<$ty> { + const MAX_ENCODED_SIZE: usize = <$ty as ::bzipper::SizedEncode>::MAX_ENCODED_SIZE; + } + }; +} + +macro_rules! impl_atomic { + { + width: $width:literal, + ty: $ty:ty, + atomic_ty: $atomic_ty:ty$(,)? + } => { + #[cfg(target_has_atomic = $width)] + #[cfg_attr(doc, doc(cfg(target_has_atomic = $width)))] + unsafe impl ::bzipper::SizedEncode for $atomic_ty { + const MAX_ENCODED_SIZE: usize = <$ty as ::bzipper::SizedEncode>::MAX_ENCODED_SIZE; + } + }; +} + //impl_numeric!(f128); //impl_numeric!(f16); impl_numeric!(f32); @@ -262,6 +286,116 @@ impl_numeric!(u32); impl_numeric!(u64); impl_numeric!(u8); +impl_tuple! { + T0, + T1, +} + +impl_tuple! { + T0, + T1, + T2, +} + +impl_tuple! { + T0, + T1, + T2, + T3, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, +} + +impl_tuple! { + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, +} + impl_non_zero!(i128); impl_non_zero!(i16); impl_non_zero!(i32); diff --git a/bzipper/src/sized_encode/tuple.rs b/bzipper/src/sized_encode/tuple.rs deleted file mode 100644 index 5a88fb7..0000000 --- a/bzipper/src/sized_encode/tuple.rs +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2024 Gabriel Bjørnager Jensen. -// -// This file is part of bZipper. -// -// bZipper is free software: you can redistribute -// it and/or modify it under the terms of the GNU -// Lesser General Public License as published by -// the Free Software Foundation, either version 3 -// of the License, or (at your option) any later -// version. -// -// bZipper is distributed in the hope that it will -// be useful, but WITHOUT ANY WARRANTY; without -// even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Less- -// er General Public License along with bZipper. If -// not, see <https://www.gnu.org/licenses/>. - -use crate::SizedEncode; - -/// Implemented for tuples with up to twelve members. -#[cfg_attr(doc, doc(fake_variadic))] -unsafe impl<T> SizedEncode for (T, ) -where - T: SizedEncode, { - - #[doc(hidden)] - const MAX_ENCODED_SIZE: usize = - T::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1> SizedEncode for (T0, T1) -where - T0: SizedEncode, - T1: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2> SizedEncode for (T0, T1, T2) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3> SizedEncode for (T0, T1, T2, T3) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4> SizedEncode for (T0, T1, T2, T3, T4) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5> SizedEncode for (T0, T1, T2, T3, T4, T5) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5, T6> SizedEncode for (T0, T1, T2, T3, T4, T5, T6) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, - T6: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE - + T6::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7> SizedEncode for (T0, T1, T2, T3, T4, T5, T6, T7) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, - T6: SizedEncode, - T7: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE - + T6::MAX_ENCODED_SIZE - + T7::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> SizedEncode for (T0, T1, T2, T3, T4, T5, T6, T7, T8) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, - T6: SizedEncode, - T7: SizedEncode, - T8: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE - + T6::MAX_ENCODED_SIZE - + T7::MAX_ENCODED_SIZE - + T8::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> SizedEncode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, - T6: SizedEncode, - T7: SizedEncode, - T8: SizedEncode, - T9: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE - + T6::MAX_ENCODED_SIZE - + T7::MAX_ENCODED_SIZE - + T8::MAX_ENCODED_SIZE - + T9::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> SizedEncode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, - T6: SizedEncode, - T7: SizedEncode, - T8: SizedEncode, - T9: SizedEncode, - T10: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE - + T6::MAX_ENCODED_SIZE - + T7::MAX_ENCODED_SIZE - + T8::MAX_ENCODED_SIZE - + T9::MAX_ENCODED_SIZE - + T10::MAX_ENCODED_SIZE; -} - -#[doc(hidden)] -unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> SizedEncode for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) -where - T0: SizedEncode, - T1: SizedEncode, - T2: SizedEncode, - T3: SizedEncode, - T4: SizedEncode, - T5: SizedEncode, - T6: SizedEncode, - T7: SizedEncode, - T8: SizedEncode, - T9: SizedEncode, - T10: SizedEncode, - T11: SizedEncode, { - const MAX_ENCODED_SIZE: usize = - T0::MAX_ENCODED_SIZE - + T1::MAX_ENCODED_SIZE - + T2::MAX_ENCODED_SIZE - + T3::MAX_ENCODED_SIZE - + T4::MAX_ENCODED_SIZE - + T5::MAX_ENCODED_SIZE - + T6::MAX_ENCODED_SIZE - + T7::MAX_ENCODED_SIZE - + T8::MAX_ENCODED_SIZE - + T9::MAX_ENCODED_SIZE - + T10::MAX_ENCODED_SIZE - + T11::MAX_ENCODED_SIZE; -} diff --git a/bzipper_benchmarks/Cargo.toml b/bzipper_benchmarks/Cargo.toml index 2bee98a..43f4236 100644 --- a/bzipper_benchmarks/Cargo.toml +++ b/bzipper_benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bzipper_benchmarks" -version = "0.8.1" +version = "0.9.0" edition = "2021" description = "bZipper benchmarks." @@ -10,7 +10,7 @@ homepage.workspace = true repository.workspace = true [dependencies] -bzipper = { path = "../bzipper", version = "0.8.0" } +bzipper = { path = "../bzipper", version = "0.9.0" } bincode = "1.3.3" ciborium = "0.2.2" diff --git a/bzipper_macros/Cargo.toml b/bzipper_macros/Cargo.toml index e87215a..818b510 100644 --- a/bzipper_macros/Cargo.toml +++ b/bzipper_macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bzipper_macros" -version = "0.8.1" +version = "0.9.0" edition = "2021" documentation = "https://docs.rs/bzipper_macros/" diff --git a/bzipper_macros/src/impls/encode_enum.rs b/bzipper_macros/src/impls/encode_enum.rs index 37acd34..7ecf3d5 100644 --- a/bzipper_macros/src/impls/encode_enum.rs +++ b/bzipper_macros/src/impls/encode_enum.rs @@ -44,7 +44,7 @@ pub fn encode_enum(data: &DataEnum) -> TokenStream { let mut field_captures = Vec::new(); for (index, field) in variant.fields.iter().enumerate() { - let capture = Ident::new(&format!("v{index}"), Span::call_site()); + let capture = Ident::new(&format!("value{index}"), Span::call_site()); field_names.push(&field.ident); field_captures.push(capture); diff --git a/bzipper_macros/src/lib.rs b/bzipper_macros/src/lib.rs index 9bb1480..db7ace7 100644 --- a/bzipper_macros/src/lib.rs +++ b/bzipper_macros/src/lib.rs @@ -25,7 +25,7 @@ use proc_macro::TokenStream; use quote::quote; -use syn::{parse_macro_input, Data, DeriveInput}; +use syn::{Data, DeriveInput}; macro_rules! use_mod { ($vis:vis $name:ident) => { @@ -43,7 +43,7 @@ mod impls; #[proc_macro_derive(Decode)] pub fn derive_decode(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); + let input = syn::parse_macro_input!(input as DeriveInput); let impl_body = match input.data { Data::Enum( ref data) => impls::decode_enum( data), @@ -73,7 +73,7 @@ pub fn derive_decode(input: TokenStream) -> TokenStream { #[proc_macro_derive(Encode)] pub fn derive_encode(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); + let input = syn::parse_macro_input!(input as DeriveInput); let impl_body = match input.data { Data::Enum( ref data) => impls::encode_enum( data), @@ -103,7 +103,7 @@ pub fn derive_encode(input: TokenStream) -> TokenStream { #[proc_macro_derive(SizedEncode)] pub fn derive_sized_encode(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); + let input = syn::parse_macro_input!(input as DeriveInput); let encode_impl_body = match input.data { Data::Enum( ref data) => impls::encode_enum( data), |