#![allow(clippy::module_name_repetitions)]
use std::num::TryFromIntError;
use ps_buffer::BufferError;
use thiserror::Error;
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum GFError {
#[error("Division by zero is undefined.")]
DivByZero,
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum PolynomialFromSliceError {
#[error("Slice was {size} bytes; a polynomial over GF(256) holds at most 255 coefficients.")]
TooLong {
size: usize,
},
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum PolynomialSetCoefficientsError {
#[error("Range {offset}..{end} exceeds maximum coefficient index 254.")]
OutOfBounds {
offset: u8,
end: usize,
},
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum PolynomialMulError {
#[error("Result degree exceeds maximum of 254.")]
DegreeOverflow,
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum PolynomialDivError {
#[error("Division by zero polynomial.")]
ZeroDivisor,
#[error(transparent)]
GFError(#[from] GFError),
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum PolynomialXorError {
#[error("Coefficient iterator exceeded maximum length of 255.")]
TooManyCoefficients,
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum EuclideanError {
#[error("Error-correction capability {t} exceeds the maximum of 127.")]
CapabilityTooHigh {
t: u8,
},
#[error(transparent)]
PolynomialDiv(#[from] PolynomialDivError),
#[error(transparent)]
PolynomialMul(#[from] PolynomialMulError),
}
#[derive(Error, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum RSConstructorError {
#[error("Parity byte count {0} is odd; parity comprises two bytes per correctable error.")]
OddParityLength(usize),
#[error("Parity count must be <= 63.")]
ParityTooHigh,
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum RSGenerateParityError {
#[error(transparent)]
Division(#[from] PolynomialDivError),
#[error(transparent)]
SetCoefficients(#[from] PolynomialSetCoefficientsError),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum RSEncodeError {
#[error(transparent)]
BufferError(#[from] BufferError),
#[error(transparent)]
RSGenerateParityError(#[from] RSGenerateParityError),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum RSComputeErrorsError {
#[error(transparent)]
GFError(#[from] GFError),
#[error(transparent)]
EuclideanError(#[from] EuclideanError),
#[error("Too many errors; input is unrecoverable.")]
TooManyErrors,
#[error("The error locator derivative evaluated to zero.")]
ZeroErrorLocatorDerivative,
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum RSDecodeError {
#[error(transparent)]
BufferError(#[from] BufferError),
#[error("Input length {received} is less than the parity length {parity_bytes}.")]
InsufficientLength {
parity_bytes: u8,
received: usize,
},
#[error(transparent)]
RSComputeErrorsError(#[from] RSComputeErrorsError),
#[error(transparent)]
RSConstructorError(#[from] RSConstructorError),
#[error("Too many errors to correct. Error computation nevertheless returned a valid polynomial, which is unlikely. Usually you'll get RSComputeErrorsError(TooManyErrors) instead.")]
TooManyErrors,
#[error(transparent)]
TryFromIntError(#[from] TryFromIntError),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum EncodeError {
#[error(transparent)]
LongEccEncodeError(#[from] LongEccEncodeError),
#[error(transparent)]
RSConstructorError(#[from] RSConstructorError),
#[error(transparent)]
RSEncodeError(#[from] RSEncodeError),
}
#[derive(Error, Debug, Clone)]
pub enum DecodeError {
#[error("Insufficient input bytes for parity count of {0}: {0} * 2 > {1}.")]
InsufficientParityBytes(u8, u8),
#[error(transparent)]
LongEccDecodeError(#[from] LongEccDecodeError),
#[error(transparent)]
RSConstructorError(#[from] RSConstructorError),
#[error(transparent)]
RSDecodeError(#[from] RSDecodeError),
}
#[derive(Error, Debug, Clone)]
pub enum EccError {
#[error(transparent)]
EncodeError(#[from] EncodeError),
#[error(transparent)]
DecodeError(#[from] DecodeError),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum LongEccHeaderConstructorError {
#[error("Generating parity failed: {0}")]
GenerateParity(#[from] RSGenerateParityError),
#[error("Full length {0} does not match the derived codeword length {1}.")]
InvalidFullLength(u32, u64),
#[error("Message length {0} does not fit within full length {1}.")]
InvalidMessageLength(u32, u32),
#[error("Invalid parity count: {0}.")]
InvalidParityCount(u8),
#[error("Invalid segment-to-parity ratio: {0} <= 2 * {1}.")]
InvalidSegmentParityRatio(u8, u8),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum LongEccHeaderFromBytesError {
#[error("Incorrect magic number: {0:x}.")]
IncorrectMagic(u16),
#[error("Incorrect version number: {0}.")]
InvalidVersion(u8),
#[error("Header checksum incorrect.")]
IncorrectChecksum,
#[error("Header error correction failed: {0}")]
CorrectionFailed(#[from] RSDecodeError),
#[error("Message length {0} does not fit within full length {1}.")]
InvalidMessageLength(u32, u32),
#[error("Invalid segment-to-parity ratio: {0} <= 2 * {1}.")]
InvalidSegmentParityRatio(u8, u8),
#[error("Full length {0} does not match the derived codeword length {1}.")]
InvalidFullLength(u32, u64),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum LongEccHeaderFromByteSliceError {
#[error("Insufficient bytes for header: got {0}, need 32.")]
InsufficientBytes(usize),
#[error(transparent)]
FromBytes(#[from] LongEccHeaderFromBytesError),
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum LongEccEncodeError {
#[error(transparent)]
BufferError(#[from] BufferError),
#[error("Parity {0} >= 64, which is too high.")]
InvalidParity(u8),
#[error("Invalid segment-to-parity ratio: {0} <= 2 * {1}.")]
InvalidSegmentParityRatio(u8, u8),
#[error("Long ECC header construction failed: {0}")]
LongEccHeaderCtor(#[from] LongEccHeaderConstructorError),
#[error(transparent)]
RSConstructorError(#[from] RSConstructorError),
#[error(transparent)]
RSGenerateParityError(#[from] RSGenerateParityError),
#[error(transparent)]
TryFromIntError(#[from] TryFromIntError),
}
#[derive(Error, Debug, Clone)]
pub enum LongEccDecodeError {
#[error(transparent)]
BufferError(#[from] BufferError),
#[error("Fast validation failed: {0}")]
FastValidate(#[from] LongEccFastValidateError),
#[error("Integrity check failed after correction.")]
IntegrityCheckFailed,
#[error("Codeword is invalid.")]
InvalidCodeword,
#[error("Failed to decode header: {0}")]
HeaderDecode(#[from] LongEccHeaderFromByteSliceError),
#[error("Failed to read data bytes.")]
ReadDataError,
#[error("Failed to read parity bytes.")]
ReadParityError,
#[error(transparent)]
RSDecodeError(#[from] RSDecodeError),
#[error(transparent)]
TryFromIntError(#[from] TryFromIntError),
}
#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)]
pub enum LongEccFastValidateError {
#[error("Header parsing failed: {0}")]
HeaderParse(#[from] crate::LongEccHeaderFromByteSliceError),
#[error("Integer conversion error: {0}")]
IntegerConversion(#[from] std::num::TryFromIntError),
}