mod byte_block;
pub use byte_block::*;
use crate::payload::{PayloadEncoded, PayloadHooks};
pub trait SignatureU32 {
fn sig() -> &'static [u8; 4];
}
pub trait CrcU32 {
fn crc(&self) -> [u8; 4];
}
pub trait PayloadCrc
where
Self: PayloadEncoded + PayloadHooks,
{
fn crc(&self, ctx: &mut Self::Context<'_>) -> std::io::Result<ByteBlock> {
let mut hasher = crc32fast::Hasher::new();
hasher.update(self.encoded(ctx)?.as_slice());
Ok(ByteBlock::Len4(hasher.finalize().to_le_bytes()))
}
fn crc_size() -> usize {
4
}
}
pub trait PayloadSignature {
fn sig(&self) -> ByteBlock;
}
pub trait StaticPayloadSignature {
fn ssig() -> ByteBlock;
}
pub trait StaticSize {
fn ssize() -> u64;
}
pub trait Size {
fn size(&self) -> u64;
}
pub trait PayloadSize: PayloadEncoded {
fn size(&self, ctx: &mut Self::Context<'_>) -> std::io::Result<u64> {
Ok(self.encoded(ctx)?.len() as u64)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{PayloadEncode, PayloadEncodeReferred, ProtocolSchema};
struct DemoPayload(Vec<u8>);
struct OwnedOnlyPayload(Vec<u8>);
impl ProtocolSchema for DemoPayload {
type Context<'a> = ();
}
impl ProtocolSchema for OwnedOnlyPayload {
type Context<'a> = ();
}
impl PayloadHooks for DemoPayload {}
impl PayloadHooks for OwnedOnlyPayload {}
impl PayloadEncode for DemoPayload {
fn encode(&self, _: &mut Self::Context<'_>) -> std::io::Result<Vec<u8>> {
Ok(self.0.clone())
}
}
impl PayloadEncode for OwnedOnlyPayload {
fn encode(&self, _: &mut Self::Context<'_>) -> std::io::Result<Vec<u8>> {
Ok(self.0.clone())
}
}
impl PayloadEncodeReferred for DemoPayload {
fn encode(&self, _: &mut Self::Context<'_>) -> std::io::Result<Option<&[u8]>> {
Ok(Some(self.0.as_slice()))
}
}
impl PayloadEncodeReferred for OwnedOnlyPayload {
fn encode(&self, _: &mut Self::Context<'_>) -> std::io::Result<Option<&[u8]>> {
Ok(None)
}
}
impl PayloadCrc for DemoPayload {}
impl PayloadSize for DemoPayload {}
impl PayloadCrc for OwnedOnlyPayload {}
impl PayloadSize for OwnedOnlyPayload {}
#[test]
fn default_payload_crc_and_size_work() {
let mut ctx = ();
let payload = DemoPayload(vec![1, 2, 3, 4]);
let crc = payload.crc(&mut ctx).expect("crc must work");
assert_eq!(crc.size(), 4);
assert_eq!(DemoPayload::crc_size(), 4);
assert_eq!(payload.size(&mut ctx).expect("size must work"), 4);
}
#[test]
fn default_payload_crc_and_size_work_for_owned_encoded_path() {
let mut ctx = ();
let payload = OwnedOnlyPayload(vec![9, 8, 7, 6, 5]);
let crc = payload.crc(&mut ctx).expect("crc must work");
let mut hasher = crc32fast::Hasher::new();
hasher.update(&[9, 8, 7, 6, 5]);
let expected_crc = hasher.finalize().to_le_bytes();
assert_eq!(crc.as_slice(), expected_crc.as_slice());
assert_eq!(payload.size(&mut ctx).expect("size must work"), 5);
}
}