use xuko_core::bytes::Bytes;
#[cfg(feature = "compress")]
pub const DEFAULT_COMPRESSION_LEVEL: i32 = zstd::DEFAULT_COMPRESSION_LEVEL;
#[derive(Debug, thiserror::Error)]
pub enum TransportDataError {
#[error("IO Error: {0}")]
IOError(#[from] std::io::Error),
}
#[derive(Clone)]
#[cfg_attr(
feature = "transport_serde",
derive(serde::Serialize, serde::Deserialize)
)]
pub struct TransportData {
bytes: Bytes,
compressed: bool,
}
impl TransportData {
pub fn new(bytes: &[u8]) -> TransportData {
Self {
bytes: Bytes::from(bytes),
compressed: false,
}
}
#[cfg(feature = "compress")]
pub fn compress(buffer: &[u8]) -> Result<TransportData, TransportDataError> {
Self::compress_with_level(buffer, DEFAULT_COMPRESSION_LEVEL)
}
#[cfg(feature = "compress")]
pub fn compress_with_level(
buffer: &[u8],
level: i32,
) -> Result<TransportData, TransportDataError> {
Ok(Self {
bytes: Bytes::from(zstd::encode_all(buffer, level)?),
compressed: true,
})
}
pub fn unwrap(&self) -> Result<Vec<u8>, TransportDataError> {
#[cfg(not(feature = "compress"))]
{
Ok(Vec::from(&*self.bytes))
}
#[cfg(feature = "compress")]
{
if self.compressed {
Ok(zstd::decode_all(&*self.bytes)?)
} else {
Ok(Vec::from(&*self.bytes))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic() -> Result<(), TransportDataError> {
let t = TransportData::new("hello".as_bytes());
let b = t.unwrap()?;
assert_eq!(b, "hello".as_bytes());
Ok(())
}
}