use std::{fmt::Debug, hash::Hash};
use crate::{core::encode::EncodeError, header::model::AddressHeader};
pub trait PayloadEncode: Debug + Send + Sync + PartialEq + PartialOrd + Hash {
fn required_size(&self, header_and_extensions_size: usize) -> usize;
unsafe fn encode_unchecked(
&self,
buf: &mut [u8],
address_header: &AddressHeader,
header_and_extensions_size: usize,
) -> usize;
fn encode(
&self,
buf: &mut [u8],
address_header: &AddressHeader,
header_and_extensions_size: usize,
) -> Result<usize, EncodeError> {
let required_size = self.required_size(header_and_extensions_size);
if buf.len() < required_size {
return Err(EncodeError::BufferTooSmall(required_size));
}
Ok(unsafe { self.encode_unchecked(buf, address_header, header_and_extensions_size) })
}
fn wire_valid(&self) -> Result<(), crate::core::encode::InvalidStructureError>;
}
impl PayloadEncode for &[u8] {
fn required_size(&self, _header_and_extensions_size: usize) -> usize {
self.len()
}
unsafe fn encode_unchecked(
&self,
buf: &mut [u8],
_address_header: &AddressHeader,
_header_and_extensions_size: usize,
) -> usize {
unsafe {
std::ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
}
self.len()
}
fn wire_valid(&self) -> Result<(), crate::core::encode::InvalidStructureError> {
Ok(())
}
}
impl PayloadEncode for Vec<u8> {
fn required_size(&self, header_and_extensions_size: usize) -> usize {
self.as_slice().required_size(header_and_extensions_size)
}
unsafe fn encode_unchecked(
&self,
buf: &mut [u8],
address_header: &AddressHeader,
header_and_extensions_size: usize,
) -> usize {
unsafe {
self.as_slice()
.encode_unchecked(buf, address_header, header_and_extensions_size)
}
}
fn wire_valid(&self) -> Result<(), crate::core::encode::InvalidStructureError> {
self.as_slice().wire_valid()
}
}