Added support for IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6

This commit is contained in:
Victor Koenders 2021-10-16 14:28:06 +02:00
parent a0469e08ef
commit 8ab730eb87
2 changed files with 139 additions and 7 deletions

View File

@ -7,6 +7,7 @@ use crate::{
use core::time::Duration;
use std::{
ffi::{CStr, CString},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
path::{Path, PathBuf},
sync::{Mutex, RwLock},
time::SystemTime,
@ -203,3 +204,117 @@ impl Decodable for PathBuf {
Ok(string.into())
}
}
impl Encodeable for IpAddr {
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), EncodeError> {
match self {
IpAddr::V4(v4) => {
0u32.encode(&mut encoder)?;
v4.encode(encoder)
}
IpAddr::V6(v6) => {
1u32.encode(&mut encoder)?;
v6.encode(encoder)
}
}
}
}
impl Decodable for IpAddr {
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
match u32::decode(&mut decoder)? {
0 => Ok(IpAddr::V4(Ipv4Addr::decode(decoder)?)),
1 => Ok(IpAddr::V6(Ipv6Addr::decode(decoder)?)),
found => Err(DecodeError::UnexpectedVariant {
min: 0,
max: 1,
found,
type_name: core::any::type_name::<IpAddr>(),
}),
}
}
}
impl Encodeable for Ipv4Addr {
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
self.octets().encode(encoder)
}
}
impl Decodable for Ipv4Addr {
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
Ok(Self::from(decoder.decode_array::<4>()?))
}
}
impl Encodeable for Ipv6Addr {
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
self.octets().encode(encoder)
}
}
impl Decodable for Ipv6Addr {
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
Ok(Self::from(decoder.decode_array::<16>()?))
}
}
impl Encodeable for SocketAddr {
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), EncodeError> {
match self {
SocketAddr::V4(v4) => {
0u32.encode(&mut encoder)?;
v4.encode(encoder)
}
SocketAddr::V6(v6) => {
1u32.encode(&mut encoder)?;
v6.encode(encoder)
}
}
}
}
impl Decodable for SocketAddr {
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
match u32::decode(&mut decoder)? {
0 => Ok(SocketAddr::V4(SocketAddrV4::decode(decoder)?)),
1 => Ok(SocketAddr::V6(SocketAddrV6::decode(decoder)?)),
found => Err(DecodeError::UnexpectedVariant {
min: 0,
max: 1,
found,
type_name: core::any::type_name::<SocketAddr>(),
}),
}
}
}
impl Encodeable for SocketAddrV4 {
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), EncodeError> {
self.ip().encode(&mut encoder)?;
self.port().encode(encoder)
}
}
impl Decodable for SocketAddrV4 {
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
let ip = Ipv4Addr::decode(&mut decoder)?;
let port = u16::decode(decoder)?;
Ok(Self::new(ip, port))
}
}
impl Encodeable for SocketAddrV6 {
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), EncodeError> {
self.ip().encode(&mut encoder)?;
self.port().encode(encoder)
}
}
impl Decodable for SocketAddrV6 {
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
let ip = Ipv6Addr::decode(&mut decoder)?;
let port = u16::decode(decoder)?;
Ok(Self::new(ip, port, 0, 0))
}
}

View File

@ -2,8 +2,13 @@
mod utils;
use std::sync::{Mutex, RwLock};
use std::{
ffi::{CStr, CString},
io::{Cursor, Seek, SeekFrom},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
path::{Path, PathBuf},
sync::{Mutex, RwLock},
};
use utils::the_same;
struct Foo {
@ -33,7 +38,7 @@ impl bincode::de::Decodable for Foo {
#[test]
fn test_std_cursor() {
let mut cursor = std::io::Cursor::<&[u8]>::new(&[5, 10]);
let mut cursor = Cursor::<&[u8]>::new(&[5, 10]);
let foo: Foo = bincode::decode_from(&mut cursor).unwrap();
assert_eq!(foo.a, 5);
@ -42,8 +47,6 @@ fn test_std_cursor() {
#[test]
fn test_std_file() {
use std::io::{Seek, SeekFrom};
let mut file = tempfile::tempfile().expect("Could not create temp file");
let bytes_written = bincode::encode_into_write(Foo { a: 30, b: 50 }, &mut file).unwrap();
@ -58,10 +61,24 @@ fn test_std_file() {
#[test]
fn test_std_commons() {
use std::ffi::{CStr, CString};
use std::path::{Path, PathBuf};
the_same(CString::new("Hello world").unwrap());
the_same(PathBuf::from("C:/Program Files/Foo"));
the_same(Ipv4Addr::LOCALHOST);
the_same(Ipv6Addr::LOCALHOST);
the_same(IpAddr::V4(Ipv4Addr::LOCALHOST));
the_same(IpAddr::V6(Ipv6Addr::LOCALHOST));
the_same(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 12345));
the_same(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 12345, 0, 0));
the_same(SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::LOCALHOST,
12345,
)));
the_same(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::LOCALHOST,
12345,
0,
0,
)));
let config = bincode::config::Default;
let mut buffer = [0u8; 1024];