diff --git a/src/features/impl_std.rs b/src/features/impl_std.rs index 4b1d8b7..ee30a86 100644 --- a/src/features/impl_std.rs +++ b/src/features/impl_std.rs @@ -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(&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(mut decoder: D) -> Result { + 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::(), + }), + } + } +} + +impl Encodeable for Ipv4Addr { + fn encode(&self, encoder: E) -> Result<(), EncodeError> { + self.octets().encode(encoder) + } +} + +impl Decodable for Ipv4Addr { + fn decode(mut decoder: D) -> Result { + Ok(Self::from(decoder.decode_array::<4>()?)) + } +} + +impl Encodeable for Ipv6Addr { + fn encode(&self, encoder: E) -> Result<(), EncodeError> { + self.octets().encode(encoder) + } +} + +impl Decodable for Ipv6Addr { + fn decode(mut decoder: D) -> Result { + Ok(Self::from(decoder.decode_array::<16>()?)) + } +} + +impl Encodeable for SocketAddr { + fn 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(mut decoder: D) -> Result { + 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::(), + }), + } + } +} + +impl Encodeable for SocketAddrV4 { + fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { + self.ip().encode(&mut encoder)?; + self.port().encode(encoder) + } +} + +impl Decodable for SocketAddrV4 { + fn decode(mut decoder: D) -> Result { + let ip = Ipv4Addr::decode(&mut decoder)?; + let port = u16::decode(decoder)?; + Ok(Self::new(ip, port)) + } +} + +impl Encodeable for SocketAddrV6 { + fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { + self.ip().encode(&mut encoder)?; + self.port().encode(encoder) + } +} + +impl Decodable for SocketAddrV6 { + fn decode(mut decoder: D) -> Result { + let ip = Ipv6Addr::decode(&mut decoder)?; + let port = u16::decode(decoder)?; + Ok(Self::new(ip, port, 0, 0)) + } +} diff --git a/tests/std.rs b/tests/std.rs index fafde3a..d94fe0a 100644 --- a/tests/std.rs +++ b/tests/std.rs @@ -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];