tx2-iff 0.1.0

PPF-IFF (Involuted Fractal Format) - Image codec using Physics-Prime Factorization, 360-prime quantization, and symplectic warping
Documentation
//! Error types for TX2-IFF codec

use thiserror::Error;

/// Result type alias for IFF operations
pub type Result<T> = std::result::Result<T, IffError>;

/// Errors that can occur during IFF encoding/decoding
#[derive(Error, Debug)]
pub enum IffError {
    /// Invalid magic number in file header
    #[error("Invalid magic number: expected 0x{expected:08X}, got 0x{got:08X}")]
    InvalidMagic { expected: u32, got: u32 },

    /// Unsupported version
    #[error("Unsupported version: {0}")]
    UnsupportedVersion(u32),

    /// Image dimensions exceed maximum
    #[error("Image dimension {dimension} exceeds maximum {max}")]
    DimensionTooLarge { dimension: u32, max: u32 },

    /// Invalid wavelet coefficient
    #[error("Invalid wavelet coefficient at ({x}, {y}, {level})")]
    InvalidWaveletCoefficient { x: usize, y: usize, level: usize },

    /// Invalid region descriptor
    #[error("Invalid region: position ({x}, {y}), size ({w}, {h})")]
    InvalidRegion {
        x: u16,
        y: u16,
        w: u16,
        h: u16,
    },

    /// Invalid vortex descriptor
    #[error("Invalid vortex at position ({x}, {y})")]
    InvalidVortex { x: u16, y: u16 },

    /// Fixed-point overflow
    #[error("Fixed-point overflow in operation: {operation}")]
    FixedPointOverflow { operation: String },

    /// Insufficient data
    #[error("Insufficient data: expected {expected} bytes, got {got}")]
    InsufficientData { expected: usize, got: usize },

    /// Corrupted bitstream
    #[error("Corrupted bitstream at offset {offset}: {reason}")]
    CorruptedBitstream { offset: usize, reason: String },

    /// IO error
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    /// Serialization error
    #[error("Serialization error: {0}")]
    Serialization(String),

    /// GPU error
    #[cfg(feature = "gpu")]
    #[error("GPU error: {0}")]
    Gpu(String),

    /// Encoding error
    #[cfg(feature = "encoder")]
    #[error("Encoding error: {0}")]
    Encoding(String),

    /// Decoding error
    #[cfg(feature = "decoder")]
    #[error("Decoding error: {0}")]
    Decoding(String),

    /// Generic error
    #[error("{0}")]
    Other(String),
}

impl From<bincode::Error> for IffError {
    fn from(err: bincode::Error) -> Self {
        IffError::Serialization(err.to_string())
    }
}

impl From<rmp_serde::encode::Error> for IffError {
    fn from(err: rmp_serde::encode::Error) -> Self {
        IffError::Serialization(err.to_string())
    }
}

impl From<rmp_serde::decode::Error> for IffError {
    fn from(err: rmp_serde::decode::Error) -> Self {
        IffError::Serialization(err.to_string())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_error_display() {
        let err = IffError::InvalidMagic {
            expected: 0x50504649,
            got: 0x12345678,
        };
        assert!(err.to_string().contains("0x50504649"));
        assert!(err.to_string().contains("0x12345678"));
    }

    #[test]
    fn test_dimension_error() {
        let err = IffError::DimensionTooLarge {
            dimension: 100000,
            max: 65536,
        };
        assert!(err.to_string().contains("100000"));
        assert!(err.to_string().contains("65536"));
    }
}