Serialise singleton, write singleton both working (barebones)

Fortune for transfer's current commit: Blessing − 吉
basic
Avril 3 years ago
parent 40656d6cc3
commit 1f5ead31c9
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,5 +1,6 @@
//! Encodings //! Encodings
use super::*; use super::*;
use ext::*;
use std::{fmt, error}; use std::{fmt, error};
use bytes::{ use bytes::{
Buf, 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 struct SendOpt
{ {
pub comp: Option<CompressionKind>, pub comp: Option<CompressionKind>,
pub encrypt: Option<EncryptionKind>, pub encrypt: Option<EncryptionKind>,
pub format: SerialFormat, pub format: SerialFormat,
} }
ref_self!(SendOpt);
/// Default buffer size for encryption transform stream copying.
pub const DEFAULT_BUFSIZE: usize = 4096; 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, where F: AsyncRead + Unpin + ?Sized,
T: AsyncWrite + Unpin + ?Sized T: AsyncWrite + Unpin + ?Sized
{ {
@ -101,8 +104,10 @@ where F: AsyncRead + Unpin + ?Sized,
Ok((written, read)) 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 { let ser = match how.format {
SerialFormat::Text => serde_json::to_vec(value)?, SerialFormat::Text => serde_json::to_vec(value)?,
SerialFormat::Binary => serde_cbor::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[..]; b = &ser[..];
&mut b &mut b
}; };
let mut ser = Vec::with_capacity(ser.len()); let mut ser = to(&ser);
if let Some(enc) = &how.encrypt { let w= if let Some(enc) = &how.encrypt {
match enc { match enc {
EncryptionKind::Chacha20((k, iv)) => { 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 { } else {
tokio::io::copy(reader, &mut ser).await?; tokio::io::copy(reader, &mut ser).await? as usize
} };
Ok(ser) Ok((ser, w))
// inner(value, how).map(|res| res.map_err(|k| SendError(Box::new((k, how.clone()))))) // 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::*; use futures::prelude::*;
// hack to avoid having to enable `try{}` feature :/ // 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)] #[derive(Debug)]
pub enum SendErrorKind pub enum SendErrorKind
{ {
@ -163,6 +172,7 @@ pub enum SendErrorKind
IO(io::Error), IO(io::Error),
} }
/// An error when sending / serialising an object.
#[derive(Debug)] #[derive(Debug)]
pub struct SendError(Box<(SendErrorKind, SendOpt)>); pub struct SendError(Box<(SendErrorKind, SendOpt)>);
@ -170,10 +180,10 @@ impl error::Error for SendError
{ {
fn source(&self) -> Option<&(dyn error::Error + 'static)> { fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match &self.0.0 Some(match &self.0.0
{ {
SendErrorKind::IO(io) => io, SendErrorKind::IO(io) => io,
_ => return None, _ => return None,
}) })
} }
} }

@ -13,6 +13,7 @@ pub use std::{
marker::{ marker::{
Send, Sync, Unpin, Send, Sync, Unpin,
}, },
borrow::{ Borrow, BorrowMut },
convert::{ convert::{
Infallible, Infallible,
TryFrom, TryFrom,
@ -27,6 +28,23 @@ pub use tokio::{
task::JoinHandle, task::JoinHandle,
}; };
/// Make this type act as a reference to itself.
///
/// Implements `AsRef<T>` 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)] #[derive(Debug, Clone)]
pub struct HexStringIter<I>(I, [u8; 2]); pub struct HexStringIter<I>(I, [u8; 2]);

@ -13,10 +13,11 @@ pub struct Request
} }
/*
pub async fn read_req<T>(mut from: T, key: ) -> eyre::Result<Request> pub async fn read_req<T>(mut from: T, key: ) -> eyre::Result<Request>
where T: AsyncRead + Unpin where T: AsyncRead + Unpin
{ {
todo!("how do we handle encryption of the request data? eh... boring") todo!("how do we handle encryption of the request data? eh... boring")
} }
*/

Loading…
Cancel
Save