#![allow(clippy::doc_markdown)]
use pyo3::create_exception;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::PyBytes;
use crate::DvplError;
create_exception!(
dvpl_engine,
PyDvplError,
PyValueError,
"Base error for all DVPL operations"
);
create_exception!(
dvpl_engine,
TooSmallError,
PyDvplError,
"Input shorter than 20 bytes (footer size)"
);
create_exception!(
dvpl_engine,
BadMagicError,
PyDvplError,
"Footer magic does not match b\"DVPL\""
);
create_exception!(
dvpl_engine,
SizeMismatchError,
PyDvplError,
"Payload length disagrees with footer"
);
create_exception!(
dvpl_engine,
CrcMismatchError,
PyDvplError,
"CRC32 of payload does not match footer checksum"
);
create_exception!(
dvpl_engine,
DecompressedSizeMismatchError,
PyDvplError,
"Decompressed output length disagrees with footer"
);
create_exception!(
dvpl_engine,
UnknownCompressionError,
PyDvplError,
"Unrecognized compression type value"
);
create_exception!(
dvpl_engine,
Lz4Error,
PyDvplError,
"Upstream lz4 error during compress/decompress"
);
impl From<DvplError> for PyErr {
fn from(err: DvplError) -> Self {
let msg = err.to_string();
match err {
DvplError::TooSmall(_) => TooSmallError::new_err(msg),
DvplError::BadMagic(_) => BadMagicError::new_err(msg),
DvplError::SizeMismatch { .. } => SizeMismatchError::new_err(msg),
DvplError::CrcMismatch { .. } => CrcMismatchError::new_err(msg),
DvplError::DecompressedSizeMismatch { .. } => {
DecompressedSizeMismatchError::new_err(msg)
}
DvplError::UnknownCompression(_) => UnknownCompressionError::new_err(msg),
DvplError::Lz4(_) => Lz4Error::new_err(msg),
}
}
}
#[pyfunction]
fn decode<'py>(py: Python<'py>, data: &[u8]) -> PyResult<Bound<'py, PyBytes>> {
let result = crate::decode(data)?;
Ok(PyBytes::new(py, &result))
}
#[pyfunction]
#[pyo3(signature = (data, comp_type=2))]
fn encode<'py>(py: Python<'py>, data: &[u8], comp_type: u32) -> PyResult<Bound<'py, PyBytes>> {
let result = crate::encode(data, comp_type)?;
Ok(PyBytes::new(py, &result))
}
#[pymodule]
fn dvpl_engine(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add("COMP_NONE", crate::COMP_NONE)?;
m.add("COMP_LZ4", crate::COMP_LZ4)?;
m.add("COMP_LZ4_HC", crate::COMP_LZ4_HC)?;
m.add_function(wrap_pyfunction!(decode, m)?)?;
m.add_function(wrap_pyfunction!(encode, m)?)?;
m.add("DvplError", m.py().get_type::<PyDvplError>())?;
m.add("TooSmallError", m.py().get_type::<TooSmallError>())?;
m.add("BadMagicError", m.py().get_type::<BadMagicError>())?;
m.add("SizeMismatchError", m.py().get_type::<SizeMismatchError>())?;
m.add("CrcMismatchError", m.py().get_type::<CrcMismatchError>())?;
m.add(
"DecompressedSizeMismatchError",
m.py().get_type::<DecompressedSizeMismatchError>(),
)?;
m.add(
"UnknownCompressionError",
m.py().get_type::<UnknownCompressionError>(),
)?;
m.add("Lz4Error", m.py().get_type::<Lz4Error>())?;
Ok(())
}