Skip to content

Commit

Permalink
use convert_from for uuid
Browse files Browse the repository at this point in the history
  • Loading branch information
vnghia committed Sep 12, 2024
1 parent b5f655b commit 4c07850
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 103 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ paste = "1.0.14"
rand = "0.8.5"
rand_chacha = "0.3.1"
serde = { version = "1.0", features = [ "derive" ] }
uuid ={ version = "1.10", features = [ "v4" ]}

# zstd doesn't compile with miri big-endian.
[target.'cfg(not(miri))'.dev-dependencies]
Expand Down
56 changes: 56 additions & 0 deletions src/derive/convert_from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
use crate::derive::{Decode, Encode};
use core::num::NonZeroUsize;

// Like [`From`] but we can implement it ourselves.
pub(crate) trait ConvertFrom<T>: Sized {
fn convert_from(value: T) -> Self;
}

pub struct ConvertIntoEncoder<T: Encode>(T::Encoder);

// Can't derive since it would bound T: Default.
impl<T: Encode> Default for ConvertIntoEncoder<T> {
fn default() -> Self {
Self(Default::default())
}
}

impl<D, T: Encode + for<'a> ConvertFrom<&'a D>> Encoder<D> for ConvertIntoEncoder<T> {
#[inline(always)]
fn encode(&mut self, t: &D) {
self.0.encode(&T::convert_from(t));
}
}

impl<T: Encode> Buffer for ConvertIntoEncoder<T> {
fn collect_into(&mut self, out: &mut Vec<u8>) {
self.0.collect_into(out);
}
fn reserve(&mut self, additional: NonZeroUsize) {
self.0.reserve(additional);
}
}

/// Decodes a `T` and then converts it with [`ConvertFrom`].
pub struct ConvertFromDecoder<'a, T: Decode<'a>>(T::Decoder);

// Can't derive since it would bound T: Default.
impl<'a, T: Decode<'a>> Default for ConvertFromDecoder<'a, T> {
fn default() -> Self {
Self(Default::default())
}
}

impl<'a, T: Decode<'a>> View<'a> for ConvertFromDecoder<'a, T> {
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
self.0.populate(input, length)
}
}

impl<'a, F: ConvertFrom<T>, T: Decode<'a>> Decoder<'a, F> for ConvertFromDecoder<'a, T> {
#[inline(always)]
fn decode(&mut self) -> F {
F::convert_from(self.0.decode())
}
}
7 changes: 5 additions & 2 deletions src/derive/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ impl<'a, T: Decode<'a>, E: Decode<'a>> Decode<'a> for core::result::Result<T, E>
macro_rules! impl_convert {
($want: path, $have: ty) => {
impl Encode for $want {
type Encoder = super::ip_addr::ConvertIntoEncoder<$have>;
type Encoder = super::convert_from::ConvertIntoEncoder<$have>;
}
impl<'a> Decode<'a> for $want {
type Decoder = super::ip_addr::ConvertFromDecoder<'a, $have>;
type Decoder = super::convert_from::ConvertFromDecoder<'a, $have>;
}
};
}
Expand Down Expand Up @@ -221,6 +221,9 @@ impl_convert!(
#[cfg(feature = "std")]
impl_convert!(std::net::SocketAddr, super::ip_addr::SocketAddrConversion);

#[cfg(feature = "uuid")]
impl_convert!(uuid::Uuid, u128);

impl<T> Encode for PhantomData<T> {
type Encoder = EmptyCoder;
}
Expand Down
57 changes: 1 addition & 56 deletions src/derive/ip_addr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
use crate::derive::{Decode, Encode};
use core::num::NonZeroUsize;
use super::convert_from::ConvertFrom;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};

macro_rules! ipvx_addr {
Expand Down Expand Up @@ -94,56 +92,3 @@ impl ConvertFrom<SocketAddrConversion> for SocketAddr {
}
}
}

// Like [`From`] but we can implement it ourselves.
pub(crate) trait ConvertFrom<T>: Sized {
fn convert_from(value: T) -> Self;
}

pub struct ConvertIntoEncoder<T: Encode>(T::Encoder);

// Can't derive since it would bound T: Default.
impl<T: Encode> Default for ConvertIntoEncoder<T> {
fn default() -> Self {
Self(Default::default())
}
}

impl<D, T: Encode + for<'a> ConvertFrom<&'a D>> Encoder<D> for ConvertIntoEncoder<T> {
#[inline(always)]
fn encode(&mut self, t: &D) {
self.0.encode(&T::convert_from(t));
}
}

impl<T: Encode> Buffer for ConvertIntoEncoder<T> {
fn collect_into(&mut self, out: &mut Vec<u8>) {
self.0.collect_into(out);
}
fn reserve(&mut self, additional: NonZeroUsize) {
self.0.reserve(additional);
}
}

/// Decodes a `T` and then converts it with [`ConvertFrom`].
pub struct ConvertFromDecoder<'a, T: Decode<'a>>(T::Decoder);

// Can't derive since it would bound T: Default.
impl<'a, T: Decode<'a>> Default for ConvertFromDecoder<'a, T> {
fn default() -> Self {
Self(Default::default())
}
}

impl<'a, T: Decode<'a>> View<'a> for ConvertFromDecoder<'a, T> {
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
self.0.populate(input, length)
}
}

impl<'a, F: ConvertFrom<T>, T: Decode<'a>> Decoder<'a, F> for ConvertFromDecoder<'a, T> {
#[inline(always)]
fn decode(&mut self) -> F {
F::convert_from(self.0.decode())
}
}
1 change: 1 addition & 0 deletions src/derive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use alloc::vec::Vec;
use core::num::NonZeroUsize;

mod array;
mod convert_from;
mod duration;
mod empty;
mod impls;
Expand Down
54 changes: 9 additions & 45 deletions src/derive/uuid.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,27 @@
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
use crate::derive::{Decode, Encode};
use core::num::NonZeroUsize;
use uuid::Uuid;

#[derive(Default)]
pub struct UuidEncoder(<u128 as Encode>::Encoder);
use super::convert_from::ConvertFrom;

impl Encoder<Uuid> for UuidEncoder {
#[inline(always)]
fn encode(&mut self, t: &Uuid) {
self.0.encode(&t.as_u128());
impl ConvertFrom<&Uuid> for u128 {
fn convert_from(value: &Uuid) -> Self {
value.as_u128()
}
}

impl Buffer for UuidEncoder {
fn collect_into(&mut self, out: &mut Vec<u8>) {
self.0.collect_into(out);
impl ConvertFrom<u128> for Uuid {
fn convert_from(value: u128) -> Self {
Uuid::from_u128(value)
}

fn reserve(&mut self, additional: NonZeroUsize) {
self.0.reserve(additional);
}
}

impl Encode for Uuid {
type Encoder = UuidEncoder;
}

#[derive(Default)]
pub struct UuidDecoder<'a>(<u128 as Decode<'a>>::Decoder);

impl<'a> View<'a> for UuidDecoder<'a> {
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
self.0.populate(input, length)
}
}

impl<'a> Decoder<'a, Uuid> for UuidDecoder<'a> {
#[inline(always)]
fn decode(&mut self) -> Uuid {
Uuid::from_u128(self.0.decode())
}
}

impl<'a> Decode<'a> for Uuid {
type Decoder = UuidDecoder<'a>;
}

#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use uuid::{uuid, Uuid};
use uuid::Uuid;

#[test]
fn test() {
assert!(crate::decode::<Uuid>(&crate::encode(&uuid!(
"d1660702-561b-48e7-add0-c222143ca13c"
)))
.is_ok());
assert!(crate::decode::<Uuid>(&crate::encode(&Uuid::new_v4())).is_ok());
}

fn bench_data() -> Vec<Uuid> {
Expand Down

0 comments on commit 4c07850

Please sign in to comment.