Tests: ser/de_singleton with normal, comp (brotli), and/or encryption (chacha) works.

Fortune for transfer's current commit: Middle blessing − 中吉
basic
Avril 3 years ago
parent 5f2f40df37
commit e900e6d398
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -75,18 +75,7 @@ pub struct SendOpt
} }
ref_self!(SendOpt); ref_self!(SendOpt);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default)] pub type RecvOpt = SendOpt;
pub struct RecvOpt
{
pub comp: Option<CompressionKind>,
pub handle_encrypted: Option<EncryptionKind>,
pub format: SerialFormat,
/// Max size of the (decompressed) input buffer.
/// 0 for unlimited.
//TODO: Do we need this?
pub max_size: usize,
}
ref_self!(RecvOpt);
/// Default buffer size for encryption transform stream copying. /// Default buffer size for encryption transform stream copying.
pub const DEFAULT_BUFSIZE: usize = 4096; pub const DEFAULT_BUFSIZE: usize = 4096;
@ -119,7 +108,7 @@ where F: AsyncRead + Unpin + ?Sized,
async fn de_singleton_inner<T: DeserializeOwned, B, F>(buf: F, mut from: &[u8], how: &RecvOpt) -> Result<T, TransformErrorKind> async fn de_singleton_inner<T: DeserializeOwned, B, F>(buf: F, mut from: &[u8], how: &RecvOpt) -> Result<T, TransformErrorKind>
where B: AsRef<[u8]> + AsyncWrite + Unpin, where B: AsRef<[u8]> + AsyncWrite + Unpin,
F: FnOnce(&[u8]) -> B F: FnOnce(&[u8]) -> B
{ {
// Decompressor // Decompressor
// The output is written to this (through writer) // The output is written to this (through writer)
@ -142,7 +131,8 @@ F: FnOnce(&[u8]) -> B
&mut buf &mut buf
}; };
// Decrypt into `writer`. // Decrypt into `writer`.
if let Some(dec) = &how.handle_encrypted {
if let Some(dec) = &how.encrypt {
// There is decryption to be done, decrypt into `writer` (which will handle decompression if needed). // There is decryption to be done, decrypt into `writer` (which will handle decompression if needed).
// Return its output buffer // Return its output buffer
match dec { match dec {
@ -150,10 +140,19 @@ F: FnOnce(&[u8]) -> B
self::cha_copy::<_, _, DEFAULT_BUFSIZE, true>(&mut &from[..], writer, k, iv).await?; self::cha_copy::<_, _, DEFAULT_BUFSIZE, true>(&mut &from[..], writer, k, iv).await?;
}, },
} }
// Required for decompression to complete
writer.flush().await?;
writer.shutdown().await?;
&buf.as_ref()[..] &buf.as_ref()[..]
} else if is_spec { } else if is_spec {
// There is decompression to be done through `writer`. Return its output buffer // There is decompression to be done through `writer`. Return its output buffer
writer.write_all(from).await?; writer.write_all(from).await?;
// Required for decompression to complete
writer.flush().await?;
writer.shutdown().await?;
&buf.as_ref()[..] &buf.as_ref()[..]
} else { } else {
// There is neither decompression nor decryption to be done, return the input reference itself // There is neither decompression nor decryption to be done, return the input reference itself
@ -195,11 +194,15 @@ where F: FnOnce(&Vec<u8>) -> V
}; };
let mut ser = to(&ser); let mut ser = to(&ser);
let w= if let Some(enc) = &how.encrypt { let w= if let Some(enc) = &how.encrypt {
match enc { let n = match enc {
EncryptionKind::Chacha20((k, iv)) => { EncryptionKind::Chacha20((k, iv)) => {
self::cha_copy::<_, _, DEFAULT_BUFSIZE, false>(reader, &mut ser, k, iv).await?.0 self::cha_copy::<_, _, DEFAULT_BUFSIZE, false>(reader, &mut ser, k, iv).await?.0
}, },
} };
// Required for compression to complete
ser.flush().await?;
ser.shutdown().await?;
n
} else { } else {
tokio::io::copy(reader, &mut ser).await? as usize tokio::io::copy(reader, &mut ser).await? as usize
}; };
@ -358,3 +361,56 @@ impl From<serde_json::Error> for TransformErrorKind
Self::Format Self::Format
} }
} }
#[cfg(test)]
mod test
{
use super::*;
async fn ser_de_with(how: SendOpt) -> eyre::Result<()>
{
use ext::*;
let obj = String::from("Hello world");
let var = ser_singleton(&obj, &how).await?;
eprintln!("Ser: {}", var.hex());
let des: String = de_singleton(&var, &how).await?;
eprintln!("De: {:?}", des);
assert_eq!(obj, des);
Ok(())
}
#[tokio::test]
async fn ser_de() -> eyre::Result<()>
{
ser_de_with(Default::default()).await
}
#[tokio::test]
async fn ser_de_comp() -> eyre::Result<()>
{
ser_de_with(SendOpt {
comp: Some(CompressionKind::Brotli),
..Default::default()
}).await
}
#[tokio::test]
async fn ser_de_enc() -> eyre::Result<()>
{
ser_de_with(SendOpt {
encrypt: Some(EncryptionKind::Chacha20(cha::keygen())),
..Default::default()
}).await
}
#[tokio::test]
async fn ser_de_comp_enc() -> eyre::Result<()>
{
ser_de_with(SendOpt {
encrypt: Some(EncryptionKind::Chacha20(cha::keygen())),
comp: Some(CompressionKind::Brotli),
..Default::default()
}).await
}
}

@ -39,8 +39,7 @@ use crate::ext::*;
/// ///
/// assert_eq!(key_encoded.parse::<Key>().unwrap(), key); /// assert_eq!(key_encoded.parse::<Key>().unwrap(), key);
/// ``` /// ```
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default, Serialize, Deserialize)]
#[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)] #[repr(transparent)]
pub struct Key([u8; KEY_SIZE]); pub struct Key([u8; KEY_SIZE]);
@ -75,8 +74,7 @@ pub struct Key([u8; KEY_SIZE]);
/// ///
/// assert_eq!(iv_encoded.parse::<IV>().unwrap(), iv); /// assert_eq!(iv_encoded.parse::<IV>().unwrap(), iv);
/// ``` /// ```
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, Default, Serialize, Deserialize)]
#[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)] #[repr(transparent)]
pub struct IV([u8; IV_SIZE]); pub struct IV([u8; IV_SIZE]);
@ -275,7 +273,7 @@ mod tests
#[test] #[test]
fn enc_dec() fn enc_dec()
{ {
let (key, iv) = crate::keygen(); let (key, iv) = crate::cha::keygen();
let key_str = key.to_string(); let key_str = key.to_string();
let iv_str = iv.to_string(); let iv_str = iv.to_string();

Loading…
Cancel
Save