use crate::{ config::Config, de::{read::Reader, BorrowDecode, BorrowDecoder, Decode, Decoder, DecoderImpl}, enc::{write::Writer, Encode, Encoder, EncoderImpl}, error::{DecodeError, EncodeError}, impl_borrow_decode, }; use core::time::Duration; use std::{ collections::{HashMap, HashSet}, ffi::{CStr, CString}, hash::Hash, io::Read, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}, path::{Path, PathBuf}, sync::{Mutex, RwLock}, time::SystemTime, }; /// Decode type `D` from the given reader with the given `Config`. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`. /// /// See the [config] module for more information about config options. /// /// [config]: config/index.html #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn decode_from_std_read, C: Config, R: std::io::Read>( src: &mut R, config: C, ) -> Result { decode_from_std_read_with_context(src, config, ()) } /// Decode type `D` from the given reader with the given `Config` and `Context`. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`. /// /// See the [config] module for more information about config options. /// /// [config]: config/index.html #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn decode_from_std_read_with_context< Context, D: Decode, C: Config, R: std::io::Read, >( src: &mut R, config: C, context: Context, ) -> Result { let reader = IoReader::new(src); let mut decoder = DecoderImpl::<_, C, Context>::new(reader, config, context); D::decode(&mut decoder) } pub(crate) struct IoReader { reader: R, } impl IoReader { pub const fn new(reader: R) -> Self { Self { reader } } } impl Reader for IoReader where R: std::io::Read, { #[inline(always)] fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> { self.reader .read_exact(bytes) .map_err(|inner| DecodeError::Io { inner, additional: bytes.len(), }) } } impl Reader for std::io::BufReader where R: std::io::Read, { fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> { self.read_exact(bytes).map_err(|inner| DecodeError::Io { inner, additional: bytes.len(), }) } #[inline] fn peek_read(&mut self, n: usize) -> Option<&[u8]> { self.buffer().get(..n) } #[inline] fn consume(&mut self, n: usize) { ::consume(self, n); } } /// Encode the given value into any type that implements `std::io::Write`, e.g. `std::fs::File`, with the given `Config`. /// See the [config] module for more information. /// Returns the amount of bytes written. /// /// [config]: config/index.html #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn encode_into_std_write( val: E, dst: &mut W, config: C, ) -> Result { let writer = IoWriter::new(dst); let mut encoder = EncoderImpl::<_, C>::new(writer, config); val.encode(&mut encoder)?; Ok(encoder.into_writer().bytes_written()) } pub(crate) struct IoWriter<'a, W: std::io::Write> { writer: &'a mut W, bytes_written: usize, } impl<'a, W: std::io::Write> IoWriter<'a, W> { pub fn new(writer: &'a mut W) -> Self { Self { writer, bytes_written: 0, } } pub const fn bytes_written(&self) -> usize { self.bytes_written } } impl Writer for IoWriter<'_, W> { #[inline(always)] fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> { self.writer .write_all(bytes) .map_err(|inner| EncodeError::Io { inner, index: self.bytes_written, })?; self.bytes_written += bytes.len(); Ok(()) } } impl Encode for &CStr { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.to_bytes().encode(encoder) } } impl Encode for CString { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.as_bytes().encode(encoder) } } impl Decode for CString { fn decode>(decoder: &mut D) -> Result { let vec = std::vec::Vec::decode(decoder)?; CString::new(vec).map_err(|inner| DecodeError::CStringNulError { position: inner.nul_position(), }) } } impl_borrow_decode!(CString); impl Encode for Mutex where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { let t = self.lock().map_err(|_| EncodeError::LockFailed { type_name: core::any::type_name::>(), })?; t.encode(encoder) } } impl Decode for Mutex where T: Decode, { fn decode>(decoder: &mut D) -> Result { let t = T::decode(decoder)?; Ok(Mutex::new(t)) } } impl<'de, T, Context> BorrowDecode<'de, Context> for Mutex where T: BorrowDecode<'de, Context>, { fn borrow_decode>( decoder: &mut D, ) -> Result { let t = T::borrow_decode(decoder)?; Ok(Mutex::new(t)) } } impl Encode for RwLock where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { let t = self.read().map_err(|_| EncodeError::LockFailed { type_name: core::any::type_name::>(), })?; t.encode(encoder) } } impl Decode for RwLock where T: Decode, { fn decode>(decoder: &mut D) -> Result { let t = T::decode(decoder)?; Ok(RwLock::new(t)) } } impl<'de, T, Context> BorrowDecode<'de, Context> for RwLock where T: BorrowDecode<'de, Context>, { fn borrow_decode>( decoder: &mut D, ) -> Result { let t = T::borrow_decode(decoder)?; Ok(RwLock::new(t)) } } impl Encode for SystemTime { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { let duration = self.duration_since(SystemTime::UNIX_EPOCH).map_err(|e| { EncodeError::InvalidSystemTime { inner: e, time: std::boxed::Box::new(*self), } })?; duration.encode(encoder) } } impl Decode for SystemTime { fn decode>(decoder: &mut D) -> Result { let duration = Duration::decode(decoder)?; match SystemTime::UNIX_EPOCH.checked_add(duration) { Some(t) => Ok(t), None => Err(DecodeError::InvalidSystemTime { duration }), } } } impl_borrow_decode!(SystemTime); impl Encode for &'_ Path { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match self.to_str() { Some(str) => str.encode(encoder), None => Err(EncodeError::InvalidPathCharacters), } } } impl<'de, Context> BorrowDecode<'de, Context> for &'de Path { fn borrow_decode>( decoder: &mut D, ) -> Result { let str = <&'de str>::borrow_decode(decoder)?; Ok(Path::new(str)) } } impl Encode for PathBuf { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.as_path().encode(encoder) } } impl Decode for PathBuf { fn decode>(decoder: &mut D) -> Result { let string = std::string::String::decode(decoder)?; Ok(string.into()) } } impl_borrow_decode!(PathBuf); impl Encode for IpAddr { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match self { IpAddr::V4(v4) => { 0u32.encode(encoder)?; v4.encode(encoder) } IpAddr::V6(v6) => { 1u32.encode(encoder)?; v6.encode(encoder) } } } } impl Decode for IpAddr { fn decode>(decoder: &mut D) -> Result { match u32::decode(decoder)? { 0 => Ok(IpAddr::V4(Ipv4Addr::decode(decoder)?)), 1 => Ok(IpAddr::V6(Ipv6Addr::decode(decoder)?)), found => Err(DecodeError::UnexpectedVariant { allowed: &crate::error::AllowedEnumVariants::Range { min: 0, max: 1 }, found, type_name: core::any::type_name::(), }), } } } impl_borrow_decode!(IpAddr); impl Encode for Ipv4Addr { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { encoder.writer().write(&self.octets()) } } impl Decode for Ipv4Addr { fn decode>(decoder: &mut D) -> Result { let mut buff = [0u8; 4]; decoder.reader().read(&mut buff)?; Ok(Self::from(buff)) } } impl_borrow_decode!(Ipv4Addr); impl Encode for Ipv6Addr { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { encoder.writer().write(&self.octets()) } } impl Decode for Ipv6Addr { fn decode>(decoder: &mut D) -> Result { let mut buff = [0u8; 16]; decoder.reader().read(&mut buff)?; Ok(Self::from(buff)) } } impl_borrow_decode!(Ipv6Addr); impl Encode for SocketAddr { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match self { SocketAddr::V4(v4) => { 0u32.encode(encoder)?; v4.encode(encoder) } SocketAddr::V6(v6) => { 1u32.encode(encoder)?; v6.encode(encoder) } } } } impl Decode for SocketAddr { fn decode>(decoder: &mut D) -> Result { match u32::decode(decoder)? { 0 => Ok(SocketAddr::V4(SocketAddrV4::decode(decoder)?)), 1 => Ok(SocketAddr::V6(SocketAddrV6::decode(decoder)?)), found => Err(DecodeError::UnexpectedVariant { allowed: &crate::error::AllowedEnumVariants::Range { min: 0, max: 1 }, found, type_name: core::any::type_name::(), }), } } } impl_borrow_decode!(SocketAddr); impl Encode for SocketAddrV4 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.ip().encode(encoder)?; self.port().encode(encoder) } } impl Decode for SocketAddrV4 { fn decode>(decoder: &mut D) -> Result { let ip = Ipv4Addr::decode(decoder)?; let port = u16::decode(decoder)?; Ok(Self::new(ip, port)) } } impl_borrow_decode!(SocketAddrV4); impl Encode for SocketAddrV6 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.ip().encode(encoder)?; self.port().encode(encoder) } } impl Decode for SocketAddrV6 { fn decode>(decoder: &mut D) -> Result { let ip = Ipv6Addr::decode(decoder)?; let port = u16::decode(decoder)?; Ok(Self::new(ip, port, 0, 0)) } } impl_borrow_decode!(SocketAddrV6); impl std::error::Error for EncodeError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Self::RefCellAlreadyBorrowed { inner, .. } => Some(inner), Self::Io { inner, .. } => Some(inner), Self::InvalidSystemTime { inner, .. } => Some(inner), _ => None, } } } impl std::error::Error for DecodeError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Self::Utf8 { inner } => Some(inner), _ => None, } } } impl Encode for HashMap where K: Encode, V: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { crate::enc::encode_slice_len(encoder, self.len())?; for (k, v) in self.iter() { Encode::encode(k, encoder)?; Encode::encode(v, encoder)?; } Ok(()) } } impl Decode for HashMap where K: Decode + Eq + std::hash::Hash, V: Decode, S: std::hash::BuildHasher + Default, { fn decode>(decoder: &mut D) -> Result { let len = crate::de::decode_slice_len(decoder)?; decoder.claim_container_read::<(K, V)>(len)?; let hash_builder: S = Default::default(); let mut map = HashMap::with_capacity_and_hasher(len, hash_builder); for _ in 0..len { // See the documentation on `unclaim_bytes_read` as to why we're doing this here decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>()); let k = K::decode(decoder)?; let v = V::decode(decoder)?; map.insert(k, v); } Ok(map) } } impl<'de, K, V, S, Context> BorrowDecode<'de, Context> for HashMap where K: BorrowDecode<'de, Context> + Eq + std::hash::Hash, V: BorrowDecode<'de, Context>, S: std::hash::BuildHasher + Default, { fn borrow_decode>( decoder: &mut D, ) -> Result { let len = crate::de::decode_slice_len(decoder)?; decoder.claim_container_read::<(K, V)>(len)?; let hash_builder: S = Default::default(); let mut map = HashMap::with_capacity_and_hasher(len, hash_builder); for _ in 0..len { // See the documentation on `unclaim_bytes_read` as to why we're doing this here decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>()); let k = K::borrow_decode(decoder)?; let v = V::borrow_decode(decoder)?; map.insert(k, v); } Ok(map) } } impl Decode for HashSet where T: Decode + Eq + Hash, S: std::hash::BuildHasher + Default, { fn decode>(decoder: &mut D) -> Result { let len = crate::de::decode_slice_len(decoder)?; decoder.claim_container_read::(len)?; let hash_builder: S = Default::default(); let mut map: HashSet = HashSet::with_capacity_and_hasher(len, hash_builder); for _ in 0..len { // See the documentation on `unclaim_bytes_read` as to why we're doing this here decoder.unclaim_bytes_read(core::mem::size_of::()); let key = T::decode(decoder)?; map.insert(key); } Ok(map) } } impl<'de, T, S, Context> BorrowDecode<'de, Context> for HashSet where T: BorrowDecode<'de, Context> + Eq + Hash, S: std::hash::BuildHasher + Default, { fn borrow_decode>( decoder: &mut D, ) -> Result { let len = crate::de::decode_slice_len(decoder)?; decoder.claim_container_read::(len)?; let mut map = HashSet::with_capacity_and_hasher(len, S::default()); for _ in 0..len { // See the documentation on `unclaim_bytes_read` as to why we're doing this here decoder.unclaim_bytes_read(core::mem::size_of::()); let key = T::borrow_decode(decoder)?; map.insert(key); } Ok(map) } } impl Encode for HashSet where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { crate::enc::encode_slice_len(encoder, self.len())?; for item in self.iter() { item.encode(encoder)?; } Ok(()) } }