Skip to content

Commit

Permalink
implement Readable and Writable for SocketAddr and its variants
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromegn committed Jan 31, 2024
1 parent fd5eefb commit 7f1e7d8
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/readable_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::borrow::{Cow, ToOwned};
use std::ops::{Range, RangeInclusive};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{BuildHasher, Hash};
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
use core::mem::MaybeUninit;

use crate::readable::Readable;
Expand Down Expand Up @@ -519,6 +520,47 @@ impl< 'a, C > Readable< 'a, C > for std::net::IpAddr where C: Context {
}
}

impl< 'a, C > Readable< 'a, C > for SocketAddrV4 where C: Context {
#[inline]
fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > {
Ok( SocketAddrV4::new( reader.read_value()?, reader.read_value()? ) )
}

#[inline]
fn minimum_bytes_needed() -> usize {
6
}
}

impl< 'a, C > Readable< 'a, C > for SocketAddrV6 where C: Context {
#[inline]
fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > {
Ok( SocketAddrV6::new( reader.read_value()?, reader.read_value()?, 0, 0 ) )
}

#[inline]
fn minimum_bytes_needed() -> usize {
18
}
}

impl< 'a, C > Readable< 'a, C > for SocketAddr where C: Context {
#[inline]
fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > {
let kind = reader.read_u8()?;
match kind {
0 => Ok( SocketAddr::V4( reader.read_value()? ) ),
1 => Ok( SocketAddr::V6( reader.read_value()? ) ),
_ => Err( crate::error::error_invalid_enum_variant() )
}
}

#[inline]
fn minimum_bytes_needed() -> usize {
7
}
}

impl< 'a, C > Readable< 'a, C > for std::time::Duration where C: Context {
#[inline]
fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > {
Expand Down
51 changes: 51 additions & 0 deletions src/writable_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::mem;
use std::borrow::{Cow, ToOwned};
use std::ops::{Range, RangeInclusive};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
use std::hash::Hash;

use crate::endianness::Endianness;
Expand Down Expand Up @@ -613,6 +614,56 @@ impl< C > Writable< C > for std::net::IpAddr where C: Context {
}
}

impl< C > Writable< C > for SocketAddrV4 where C: Context {
#[inline]
fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > {
self.ip().write_to( writer )?;
writer.write_u16( self.port() )
}

#[inline]
fn bytes_needed( &self ) -> Result< usize, C::Error > {
Ok( 6 )
}
}

impl< C > Writable< C > for SocketAddrV6 where C: Context {
#[inline]
fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > {
self.ip().write_to( writer )?;
writer.write_u16( self.port() )
}

#[inline]
fn bytes_needed( &self ) -> Result< usize, C::Error > {
Ok( 18 )
}
}

impl< C > Writable< C > for SocketAddr where C: Context {
#[inline]
fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > {
match self {
SocketAddr::V4( address ) => {
writer.write_u8( 0 )?;
address.write_to( writer )
},
SocketAddr::V6( address ) => {
writer.write_u8( 1 )?;
address.write_to( writer )
}
}
}

#[inline]
fn bytes_needed( &self ) -> Result< usize, C::Error > {
match self {
SocketAddr::V4( address ) => Writable::< C >::bytes_needed( address ).map( |count| count + 1 ),
SocketAddr::V6( address ) => Writable::< C >::bytes_needed( address ).map( |count| count + 1 )
}
}
}

impl< C > Writable< C > for std::time::Duration where C: Context {
#[inline]
fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > {
Expand Down
25 changes: 25 additions & 0 deletions tests/serialization_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::ops::{Range, RangeInclusive};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::fmt::Debug;
use std::num::NonZeroU32;
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};

#[allow(unused_imports)]
use speedy::{Readable, Writable, Endianness};
Expand Down Expand Up @@ -1497,6 +1498,30 @@ symmetric_tests! {
be = [1, 0x20, 0x01, 0x07, 0x20, 0x15, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0xa1, 0x00],
minimum_bytes = 5
}
socket_addr_v4 for SocketAddrV4 {
in = SocketAddrV4::new( std::net::Ipv4Addr::new( 127, 0, 0, 1 ), 33 ),
le = [1, 0, 0, 127, 33, 0],
be = [127, 0, 0, 1, 0, 33],
minimum_bytes = 6
}
socket_addr_v6 for SocketAddrV6 {
in = SocketAddrV6::new( std::net::Ipv6Addr::new( 0x2001, 0x720, 0x1500, 0x1, 0, 0, 0, 0xa100 ), 33, 0, 0 ),
le = [0x00, 0xa1, 0, 0, 0, 0, 0, 0, 0x01, 0x00, 0x00, 0x15, 0x20, 0x07, 0x01, 0x20, 33, 0],
be = [0x20, 0x01, 0x07, 0x20, 0x15, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0xa1, 0x00, 0, 33],
minimum_bytes = 18
}
socket_addr_ipv4 for SocketAddr {
in = SocketAddr::V4( SocketAddrV4::new( std::net::Ipv4Addr::new( 127, 0, 0, 1 ), 33 ) ),
le = [0, 1, 0, 0, 127, 33, 0],
be = [0, 127, 0, 0, 1, 0, 33],
minimum_bytes = 7
}
socket_addr_ipv6 for SocketAddr {
in = SocketAddr::V6( SocketAddrV6::new( std::net::Ipv6Addr::new( 0x2001, 0x720, 0x1500, 0x1, 0, 0, 0, 0xa100 ), 33, 0, 0 ) ),
le = [1, 0x00, 0xa1, 0, 0, 0, 0, 0, 0, 0x01, 0x00, 0x00, 0x15, 0x20, 0x07, 0x01, 0x20, 33, 0],
be = [1, 0x20, 0x01, 0x07, 0x20, 0x15, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0xa1, 0x00, 0, 33],
minimum_bytes = 19
}
duration for std::time::Duration {
in = std::time::Duration::new( 1, 2 ),
le = [
Expand Down

0 comments on commit 7f1e7d8

Please sign in to comment.