Skip to content

Commit 4c07850

Browse files
committed
use convert_from for uuid
1 parent b5f655b commit 4c07850

File tree

6 files changed

+73
-103
lines changed

6 files changed

+73
-103
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ paste = "1.0.14"
3131
rand = "0.8.5"
3232
rand_chacha = "0.3.1"
3333
serde = { version = "1.0", features = [ "derive" ] }
34+
uuid ={ version = "1.10", features = [ "v4" ]}
3435

3536
# zstd doesn't compile with miri big-endian.
3637
[target.'cfg(not(miri))'.dev-dependencies]

src/derive/convert_from.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
2+
use crate::derive::{Decode, Encode};
3+
use core::num::NonZeroUsize;
4+
5+
// Like [`From`] but we can implement it ourselves.
6+
pub(crate) trait ConvertFrom<T>: Sized {
7+
fn convert_from(value: T) -> Self;
8+
}
9+
10+
pub struct ConvertIntoEncoder<T: Encode>(T::Encoder);
11+
12+
// Can't derive since it would bound T: Default.
13+
impl<T: Encode> Default for ConvertIntoEncoder<T> {
14+
fn default() -> Self {
15+
Self(Default::default())
16+
}
17+
}
18+
19+
impl<D, T: Encode + for<'a> ConvertFrom<&'a D>> Encoder<D> for ConvertIntoEncoder<T> {
20+
#[inline(always)]
21+
fn encode(&mut self, t: &D) {
22+
self.0.encode(&T::convert_from(t));
23+
}
24+
}
25+
26+
impl<T: Encode> Buffer for ConvertIntoEncoder<T> {
27+
fn collect_into(&mut self, out: &mut Vec<u8>) {
28+
self.0.collect_into(out);
29+
}
30+
fn reserve(&mut self, additional: NonZeroUsize) {
31+
self.0.reserve(additional);
32+
}
33+
}
34+
35+
/// Decodes a `T` and then converts it with [`ConvertFrom`].
36+
pub struct ConvertFromDecoder<'a, T: Decode<'a>>(T::Decoder);
37+
38+
// Can't derive since it would bound T: Default.
39+
impl<'a, T: Decode<'a>> Default for ConvertFromDecoder<'a, T> {
40+
fn default() -> Self {
41+
Self(Default::default())
42+
}
43+
}
44+
45+
impl<'a, T: Decode<'a>> View<'a> for ConvertFromDecoder<'a, T> {
46+
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
47+
self.0.populate(input, length)
48+
}
49+
}
50+
51+
impl<'a, F: ConvertFrom<T>, T: Decode<'a>> Decoder<'a, F> for ConvertFromDecoder<'a, T> {
52+
#[inline(always)]
53+
fn decode(&mut self) -> F {
54+
F::convert_from(self.0.decode())
55+
}
56+
}

src/derive/impls.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,10 @@ impl<'a, T: Decode<'a>, E: Decode<'a>> Decode<'a> for core::result::Result<T, E>
187187
macro_rules! impl_convert {
188188
($want: path, $have: ty) => {
189189
impl Encode for $want {
190-
type Encoder = super::ip_addr::ConvertIntoEncoder<$have>;
190+
type Encoder = super::convert_from::ConvertIntoEncoder<$have>;
191191
}
192192
impl<'a> Decode<'a> for $want {
193-
type Decoder = super::ip_addr::ConvertFromDecoder<'a, $have>;
193+
type Decoder = super::convert_from::ConvertFromDecoder<'a, $have>;
194194
}
195195
};
196196
}
@@ -221,6 +221,9 @@ impl_convert!(
221221
#[cfg(feature = "std")]
222222
impl_convert!(std::net::SocketAddr, super::ip_addr::SocketAddrConversion);
223223

224+
#[cfg(feature = "uuid")]
225+
impl_convert!(uuid::Uuid, u128);
226+
224227
impl<T> Encode for PhantomData<T> {
225228
type Encoder = EmptyCoder;
226229
}

src/derive/ip_addr.rs

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
2-
use crate::derive::{Decode, Encode};
3-
use core::num::NonZeroUsize;
1+
use super::convert_from::ConvertFrom;
42
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
53

64
macro_rules! ipvx_addr {
@@ -94,56 +92,3 @@ impl ConvertFrom<SocketAddrConversion> for SocketAddr {
9492
}
9593
}
9694
}
97-
98-
// Like [`From`] but we can implement it ourselves.
99-
pub(crate) trait ConvertFrom<T>: Sized {
100-
fn convert_from(value: T) -> Self;
101-
}
102-
103-
pub struct ConvertIntoEncoder<T: Encode>(T::Encoder);
104-
105-
// Can't derive since it would bound T: Default.
106-
impl<T: Encode> Default for ConvertIntoEncoder<T> {
107-
fn default() -> Self {
108-
Self(Default::default())
109-
}
110-
}
111-
112-
impl<D, T: Encode + for<'a> ConvertFrom<&'a D>> Encoder<D> for ConvertIntoEncoder<T> {
113-
#[inline(always)]
114-
fn encode(&mut self, t: &D) {
115-
self.0.encode(&T::convert_from(t));
116-
}
117-
}
118-
119-
impl<T: Encode> Buffer for ConvertIntoEncoder<T> {
120-
fn collect_into(&mut self, out: &mut Vec<u8>) {
121-
self.0.collect_into(out);
122-
}
123-
fn reserve(&mut self, additional: NonZeroUsize) {
124-
self.0.reserve(additional);
125-
}
126-
}
127-
128-
/// Decodes a `T` and then converts it with [`ConvertFrom`].
129-
pub struct ConvertFromDecoder<'a, T: Decode<'a>>(T::Decoder);
130-
131-
// Can't derive since it would bound T: Default.
132-
impl<'a, T: Decode<'a>> Default for ConvertFromDecoder<'a, T> {
133-
fn default() -> Self {
134-
Self(Default::default())
135-
}
136-
}
137-
138-
impl<'a, T: Decode<'a>> View<'a> for ConvertFromDecoder<'a, T> {
139-
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
140-
self.0.populate(input, length)
141-
}
142-
}
143-
144-
impl<'a, F: ConvertFrom<T>, T: Decode<'a>> Decoder<'a, F> for ConvertFromDecoder<'a, T> {
145-
#[inline(always)]
146-
fn decode(&mut self) -> F {
147-
F::convert_from(self.0.decode())
148-
}
149-
}

src/derive/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use alloc::vec::Vec;
55
use core::num::NonZeroUsize;
66

77
mod array;
8+
mod convert_from;
89
mod duration;
910
mod empty;
1011
mod impls;

src/derive/uuid.rs

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,27 @@
1-
use crate::coder::{Buffer, Decoder, Encoder, Result, View};
2-
use crate::derive::{Decode, Encode};
3-
use core::num::NonZeroUsize;
41
use uuid::Uuid;
52

6-
#[derive(Default)]
7-
pub struct UuidEncoder(<u128 as Encode>::Encoder);
3+
use super::convert_from::ConvertFrom;
84

9-
impl Encoder<Uuid> for UuidEncoder {
10-
#[inline(always)]
11-
fn encode(&mut self, t: &Uuid) {
12-
self.0.encode(&t.as_u128());
5+
impl ConvertFrom<&Uuid> for u128 {
6+
fn convert_from(value: &Uuid) -> Self {
7+
value.as_u128()
138
}
149
}
1510

16-
impl Buffer for UuidEncoder {
17-
fn collect_into(&mut self, out: &mut Vec<u8>) {
18-
self.0.collect_into(out);
11+
impl ConvertFrom<u128> for Uuid {
12+
fn convert_from(value: u128) -> Self {
13+
Uuid::from_u128(value)
1914
}
20-
21-
fn reserve(&mut self, additional: NonZeroUsize) {
22-
self.0.reserve(additional);
23-
}
24-
}
25-
26-
impl Encode for Uuid {
27-
type Encoder = UuidEncoder;
28-
}
29-
30-
#[derive(Default)]
31-
pub struct UuidDecoder<'a>(<u128 as Decode<'a>>::Decoder);
32-
33-
impl<'a> View<'a> for UuidDecoder<'a> {
34-
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
35-
self.0.populate(input, length)
36-
}
37-
}
38-
39-
impl<'a> Decoder<'a, Uuid> for UuidDecoder<'a> {
40-
#[inline(always)]
41-
fn decode(&mut self) -> Uuid {
42-
Uuid::from_u128(self.0.decode())
43-
}
44-
}
45-
46-
impl<'a> Decode<'a> for Uuid {
47-
type Decoder = UuidDecoder<'a>;
4815
}
4916

5017
#[cfg(test)]
5118
mod tests {
5219
use alloc::vec::Vec;
53-
use uuid::{uuid, Uuid};
20+
use uuid::Uuid;
5421

5522
#[test]
5623
fn test() {
57-
assert!(crate::decode::<Uuid>(&crate::encode(&uuid!(
58-
"d1660702-561b-48e7-add0-c222143ca13c"
59-
)))
60-
.is_ok());
24+
assert!(crate::decode::<Uuid>(&crate::encode(&Uuid::new_v4())).is_ok());
6125
}
6226

6327
fn bench_data() -> Vec<Uuid> {

0 commit comments

Comments
 (0)