|
|
|
@ -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<CompressionKind>,
|
|
|
|
|
pub encrypt: Option<EncryptionKind>,
|
|
|
|
|
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<F, T, const BUFSIZE: usize, const DECRYPT: bool>(from: &mut F, to: &mut T, key: &key::Key, iv: &key::IV) -> io::Result<(usize, usize)>
|
|
|
|
|
async fn cha_copy<F, T, const BUFSIZE: usize, const DECRYPT: bool>(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<T: Serialize>(value: &T, how: &SendOpt) -> Result<Vec<u8>, SendErrorKind>
|
|
|
|
|
async fn ser_singleton_inner<T: Serialize, V: AsyncWrite + Unpin, F>(to: F, value: &T, how: impl AsRef<SendOpt>) -> Result<(V, usize), SendErrorKind>
|
|
|
|
|
where F: FnOnce(&Vec<u8>) -> 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<T: Serialize>(value: &T, how: &SendOpt) -> Result<V
|
|
|
|
|
b = &ser[..];
|
|
|
|
|
&mut b
|
|
|
|
|
};
|
|
|
|
|
let mut ser = Vec::with_capacity(ser.len());
|
|
|
|
|
if let Some(enc) = &how.encrypt {
|
|
|
|
|
let mut ser = to(&ser);
|
|
|
|
|
let w= if let Some(enc) = &how.encrypt {
|
|
|
|
|
match enc {
|
|
|
|
|
EncryptionKind::Chacha20((k, iv)) => {
|
|
|
|
|
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<T: Serialize>(value: &T, how: &SendOpt) -> Result<V
|
|
|
|
|
{
|
|
|
|
|
use futures::prelude::*;
|
|
|
|
|
// hack to avoid having to enable `try{}` feature :/
|
|
|
|
|
ser_singleton_inner(value, how).map_err(|k| SendError(Box::new((k, how.clone()))))
|
|
|
|
|
ser_singleton_inner(|c| Vec::with_capacity(c.len()), value, how)
|
|
|
|
|
.map_ok(|(v, _)| v)
|
|
|
|
|
.map_err(|k| SendError(Box::new((k, how.clone()))))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn write_singleton<T: Serialize, S: ?Sized + AsyncWrite + Unpin>(to: &mut S, value: &T, how: &SendOpt) -> Result<usize, SendError>
|
|
|
|
|
/// Serialise a single object to a stream with the method described by `how`.
|
|
|
|
|
#[inline] pub async fn write_singleton<T: Serialize, S: ?Sized + AsyncWrite + Unpin>(to: &mut S, value: &T, how: &SendOpt) -> Result<usize, SendError>
|
|
|
|
|
{
|
|
|
|
|
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,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|