diff --git a/src/enc.rs b/src/enc.rs index 1aa30a7..a8d240c 100644 --- a/src/enc.rs +++ b/src/enc.rs @@ -1,5 +1,6 @@ //! Encodings use super::*; +use ext::*; use std::{fmt, error}; use bytes::{ Buf, @@ -65,17 +66,19 @@ impl Default for SerialFormat } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default)] pub struct SendOpt { pub comp: Option, pub encrypt: Option, pub format: SerialFormat, } +ref_self!(SendOpt); +/// Default buffer size for encryption transform stream copying. pub const DEFAULT_BUFSIZE: usize = 4096; -pub async fn cha_copy(from: &mut F, to: &mut T, key: &key::Key, iv: &key::IV) -> io::Result<(usize, usize)> +async fn cha_copy(from: &mut F, to: &mut T, key: &key::Key, iv: &key::IV) -> io::Result<(usize, usize)> where F: AsyncRead + Unpin + ?Sized, T: AsyncWrite + Unpin + ?Sized { @@ -101,8 +104,10 @@ where F: AsyncRead + Unpin + ?Sized, Ok((written, read)) } -async fn ser_singleton_inner(value: &T, how: &SendOpt) -> Result, SendErrorKind> +async fn ser_singleton_inner(to: F, value: &T, how: impl AsRef) -> Result<(V, usize), SendErrorKind> +where F: FnOnce(&Vec) -> V { + let how = how.as_ref(); let ser = match how.format { SerialFormat::Text => serde_json::to_vec(value)?, SerialFormat::Binary => serde_cbor::to_vec(value)?, @@ -122,17 +127,17 @@ async fn ser_singleton_inner(value: &T, how: &SendOpt) -> Result { - self::cha_copy::<_, _, 4096, false>(reader, &mut ser, k, iv).await?; + self::cha_copy::<_, _, DEFAULT_BUFSIZE, false>(reader, &mut ser, k, iv).await?.0 }, } } else { - tokio::io::copy(reader, &mut ser).await?; - } - Ok(ser) + tokio::io::copy(reader, &mut ser).await? as usize + }; + Ok((ser, w)) // inner(value, how).map(|res| res.map_err(|k| SendError(Box::new((k, how.clone()))))) } @@ -140,15 +145,19 @@ async fn ser_singleton_inner(value: &T, how: &SendOpt) -> Result(to: &mut S, value: &T, how: &SendOpt) -> Result +/// Serialise a single object to a stream with the method described by `how`. +#[inline] pub async fn write_singleton(to: &mut S, value: &T, how: &SendOpt) -> Result { - Ok(0) + ser_singleton_inner(|_| to, value, &how).await + .map_err(|k| SendError(Box::new((k, how.to_owned())))) + .map(|(_, n)| n) } - #[derive(Debug)] pub enum SendErrorKind { @@ -163,6 +172,7 @@ pub enum SendErrorKind IO(io::Error), } +/// An error when sending / serialising an object. #[derive(Debug)] pub struct SendError(Box<(SendErrorKind, SendOpt)>); @@ -170,10 +180,10 @@ impl error::Error for SendError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { Some(match &self.0.0 - { - SendErrorKind::IO(io) => io, - _ => return None, - }) + { + SendErrorKind::IO(io) => io, + _ => return None, + }) } } diff --git a/src/ext.rs b/src/ext.rs index 7c30f0d..bc00a91 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -13,6 +13,7 @@ pub use std::{ marker::{ Send, Sync, Unpin, }, + borrow::{ Borrow, BorrowMut }, convert::{ Infallible, TryFrom, @@ -27,6 +28,23 @@ pub use tokio::{ task::JoinHandle, }; +/// Make this type act as a reference to itself. +/// +/// Implements `AsRef` for type `T`. +#[macro_export] macro_rules! ref_self { + ($type:ty) => { + impl AsRef<$type> for $type + { + #[inline] fn as_ref(&self) -> &$type + { + self + } + } + + } +} + + #[derive(Debug, Clone)] pub struct HexStringIter(I, [u8; 2]); diff --git a/src/send/handshake.rs b/src/send/handshake.rs index 4b7cf97..68462b7 100644 --- a/src/send/handshake.rs +++ b/src/send/handshake.rs @@ -13,10 +13,11 @@ pub struct Request } - +/* pub async fn read_req(mut from: T, key: ) -> eyre::Result where T: AsyncRead + Unpin { todo!("how do we handle encryption of the request data? eh... boring") } +*/