use std::fmt;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CodingError {
InvalidLength {
n: usize,
},
InvalidDistance {
d: usize,
n: usize,
},
LinearAlgebra {
op: &'static str,
detail: String,
},
EnumerationTooLarge {
codewords: String,
n: usize,
limit: String,
},
LengthTooLarge {
n: usize,
cap: usize,
},
MalformedDistribution {
reason: String,
},
LpFailure {
detail: String,
},
InvalidAlphabet {
q: String,
reason: String,
},
}
impl fmt::Display for CodingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CodingError::InvalidLength { n } => write!(
f,
"a linear code needs a positive length; got n = {n}, which leaves \
no coordinate for a weight to count"
),
CodingError::InvalidDistance { d, n } => {
write!(f, "the minimum distance must lie in 1..={n}; got d = {d}")
}
CodingError::LinearAlgebra { op, detail } => {
write!(f, "the GF(q) backend refused `{op}`: {detail}")
}
CodingError::EnumerationTooLarge {
codewords,
n,
limit,
} => write!(
f,
"exhaustive enumeration of {codewords} codewords of length {n} is \
past the cap ({limit}); there is no partial answer, because a \
minimum distance from a truncated search is an upper bound on \
the distance wearing the distance's name"
),
CodingError::LengthTooLarge { n, cap } => write!(
f,
"the Delsarte programme is capped at length {cap}; got n = {n}"
),
CodingError::MalformedDistribution { reason } => write!(
f,
"this is not the weight distribution of a linear code: {reason}"
),
CodingError::LpFailure { detail } => write!(
f,
"the exact simplex did not certify a bound: {detail}; the Delsarte \
programme is feasible and bounded by construction, so this is a bug \
and the (uncertified) number is withheld rather than returned"
),
CodingError::InvalidAlphabet { q, reason } => {
write!(f, "unusable alphabet size q = {q}: {reason}")
}
}
}
}
impl std::error::Error for CodingError {}
impl crate::errors::AlkahestError for CodingError {
fn code(&self) -> &'static str {
match self {
CodingError::InvalidLength { .. } => "E-CODE-001",
CodingError::InvalidDistance { .. } => "E-CODE-002",
CodingError::LinearAlgebra { .. } => "E-CODE-003",
CodingError::EnumerationTooLarge { .. } => "E-CODE-004",
CodingError::LengthTooLarge { .. } => "E-CODE-005",
CodingError::MalformedDistribution { .. } => "E-CODE-006",
CodingError::LpFailure { .. } => "E-CODE-007",
CodingError::InvalidAlphabet { .. } => "E-CODE-008",
}
}
fn remediation(&self) -> Option<&'static str> {
crate::errors::codes::REGISTRY
.iter()
.find(|spec| spec.code == crate::errors::AlkahestError::code(self))
.and_then(|spec| spec.remediation)
}
}
pub(crate) fn wrap_ff(op: &'static str, e: crate::ffield::FiniteFieldError) -> CodingError {
use crate::errors::AlkahestError;
let code = AlkahestError::code(&e);
CodingError::LinearAlgebra {
op,
detail: format!("{code}: {e}"),
}
}