Skip to content

Commit

Permalink
Refactor. (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
finnbear authored Sep 20, 2024
1 parent 73c73b0 commit 195318d
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 64 deletions.
15 changes: 15 additions & 0 deletions src/derive/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@ use crate::coder::{Buffer, Decoder, Encoder, Result, View};
use crate::derive::{Decode, Encode};
use core::num::NonZeroUsize;

#[allow(unused)]
macro_rules! impl_convert {
($want: path, $have: ty) => {
impl Encode for $want {
type Encoder = crate::derive::convert::ConvertIntoEncoder<$have>;
}
impl<'a> Decode<'a> for $want {
type Decoder = crate::derive::convert::ConvertFromDecoder<'a, $have>;
}
};
}

#[allow(unused)]
pub(crate) use impl_convert;

// Like [`From`] but we can implement it ourselves.
pub(crate) trait ConvertFrom<T>: Sized {
fn convert_from(value: T) -> Self;
Expand Down
99 changes: 42 additions & 57 deletions src/derive/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::num::*;

#[cfg(feature = "std")]
use core::hash::{BuildHasher, Hash};
#[cfg(feature = "std")]
use std::collections::{HashMap, HashSet};

macro_rules! impl_both {
($t:ty, $encoder:ident, $decoder:ident) => {
impl Encode for $t {
Expand All @@ -33,6 +28,7 @@ macro_rules! impl_both {
}
};
}
pub(crate) use impl_both;
impl_both!(bool, BoolEncoder, BoolDecoder);
impl_both!(f32, F32Encoder, F32Decoder);
impl_both!(String, StrEncoder, StrDecoder);
Expand Down Expand Up @@ -150,31 +146,13 @@ impl<T: Encode> Encode for BTreeSet<T> {
impl<'a, T: Decode<'a> + Ord> Decode<'a> for BTreeSet<T> {
type Decoder = VecDecoder<'a, T>;
}
#[cfg(feature = "std")]
impl<T: Encode, S> Encode for HashSet<T, S> {
type Encoder = VecEncoder<T>;
}
#[cfg(feature = "std")]
impl<'a, T: Decode<'a> + Eq + Hash, S: BuildHasher + Default> Decode<'a> for HashSet<T, S> {
type Decoder = VecDecoder<'a, T>;
}

impl<K: Encode, V: Encode> Encode for BTreeMap<K, V> {
type Encoder = MapEncoder<K, V>;
}
impl<'a, K: Decode<'a> + Ord, V: Decode<'a>> Decode<'a> for BTreeMap<K, V> {
type Decoder = MapDecoder<'a, K, V>;
}
#[cfg(feature = "std")]
impl<K: Encode, V: Encode, S> Encode for HashMap<K, V, S> {
type Encoder = MapEncoder<K, V>;
}
#[cfg(feature = "std")]
impl<'a, K: Decode<'a> + Eq + Hash, V: Decode<'a>, S: BuildHasher + Default> Decode<'a>
for HashMap<K, V, S>
{
type Decoder = MapDecoder<'a, K, V>;
}

impl<T: Encode, E: Encode> Encode for core::result::Result<T, E> {
type Encoder = ResultEncoder<T, E>;
Expand All @@ -184,42 +162,49 @@ impl<'a, T: Decode<'a>, E: Decode<'a>> Decode<'a> for core::result::Result<T, E>
}

#[cfg(feature = "std")]
macro_rules! impl_convert {
($want: path, $have: ty) => {
impl Encode for $want {
type Encoder = super::convert::ConvertIntoEncoder<$have>;
}
impl<'a> Decode<'a> for $want {
type Decoder = super::convert::ConvertFromDecoder<'a, $have>;
}
};
}
mod with_std {
use super::*;
use crate::derive::convert::impl_convert;
use core::hash::{BuildHasher, Hash};
use std::collections::{HashMap, HashSet};

impl<T: Encode, S> Encode for HashSet<T, S> {
type Encoder = VecEncoder<T>;
}
impl<'a, T: Decode<'a> + Eq + Hash, S: BuildHasher + Default> Decode<'a> for HashSet<T, S> {
type Decoder = VecDecoder<'a, T>;
}
impl<K: Encode, V: Encode, S> Encode for HashMap<K, V, S> {
type Encoder = MapEncoder<K, V>;
}
impl<'a, K: Decode<'a> + Eq + Hash, V: Decode<'a>, S: BuildHasher + Default> Decode<'a>
for HashMap<K, V, S>
{
type Decoder = MapDecoder<'a, K, V>;
}

#[cfg(feature = "std")]
macro_rules! impl_ipvx_addr {
($addr: ident, $repr: ident) => {
impl_convert!(std::net::$addr, $repr);
};
}
macro_rules! impl_ipvx_addr {
($addr: ident, $repr: ident) => {
impl_convert!(std::net::$addr, $repr);
};
}

#[cfg(feature = "std")]
impl_ipvx_addr!(Ipv4Addr, u32);
#[cfg(feature = "std")]
impl_ipvx_addr!(Ipv6Addr, u128);
#[cfg(feature = "std")]
impl_convert!(std::net::IpAddr, super::ip_addr::IpAddrConversion);
#[cfg(feature = "std")]
impl_convert!(
std::net::SocketAddrV4,
super::ip_addr::SocketAddrV4Conversion
);
#[cfg(feature = "std")]
impl_convert!(
std::net::SocketAddrV6,
super::ip_addr::SocketAddrV6Conversion
);
#[cfg(feature = "std")]
impl_convert!(std::net::SocketAddr, super::ip_addr::SocketAddrConversion);
impl_ipvx_addr!(Ipv4Addr, u32);
impl_ipvx_addr!(Ipv6Addr, u128);
impl_convert!(std::net::IpAddr, crate::derive::ip_addr::IpAddrConversion);
impl_convert!(
std::net::SocketAddrV4,
crate::derive::ip_addr::SocketAddrV4Conversion
);
impl_convert!(
std::net::SocketAddrV6,
crate::derive::ip_addr::SocketAddrV6Conversion
);
impl_convert!(
std::net::SocketAddr,
crate::derive::ip_addr::SocketAddrConversion
);
}

impl<T> Encode for PhantomData<T> {
type Encoder = EmptyCoder;
Expand Down
2 changes: 1 addition & 1 deletion src/derive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloc::vec::Vec;
use core::num::NonZeroUsize;

mod array;
mod convert;
pub(crate) mod convert;
mod duration;
mod empty;
mod impls;
Expand Down
14 changes: 8 additions & 6 deletions src/serde/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,23 @@ macro_rules! specify {
_ => {
// Either create the correct decoder if unspecified or diverge via panic/error.
#[cold]
#[rustfmt::skip]
fn cold<'de>(decoder: &mut SerdeDecoder<'de>, input: &mut &'de [u8]) -> Result<()> {
let &mut SerdeDecoder::Unspecified { length } = decoder else {
type_changed!()
};
type_changed!()
};
*decoder = SerdeDecoder::$variant(Default::default());
decoder.populate(input, length)
}
cold(&mut *$self.decoder, &mut *$self.input)?;
}
}
#[rustfmt::skip]
let SerdeDecoder::$variant(d) = &mut *$self.decoder else {
// Safety: `cold` gets called when decoder isn't the correct decoder. `cold` either
// errors or sets lazy to the correct decoder.
unsafe { core::hint::unreachable_unchecked() };
};
// Safety: `cold` gets called when decoder isn't the correct decoder. `cold` either
// errors or sets lazy to the correct decoder.
unsafe { core::hint::unreachable_unchecked() };
};
d
}};
}
Expand Down

0 comments on commit 195318d

Please sign in to comment.