use std::fmt;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum NumberFieldError {
EmptyDefiningPolynomial,
DegreeOutOfRange {
degree: i64,
max: usize,
},
Reducible {
poly: String,
factor: String,
},
MalformedCoefficient {
text: String,
},
NotInvertible,
FieldMismatch {
lhs: String,
rhs: String,
},
CoefficientCountMismatch {
got: usize,
degree: usize,
},
CyclotomicOrderOutOfRange {
n: u64,
max: usize,
},
}
impl fmt::Display for NumberFieldError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NumberFieldError::EmptyDefiningPolynomial => write!(
f,
"the defining polynomial is zero; a number field needs a \
polynomial of degree at least 1"
),
NumberFieldError::DegreeOutOfRange { degree, max } => write!(
f,
"defining polynomial of degree {degree} is outside 1..={max}; \
degree 0 would make Q[x]/(f) the zero ring, not a field"
),
NumberFieldError::Reducible { poly, factor } => write!(
f,
"{poly} is reducible over Q ({factor} divides it), so Q[x]/(f) \
is a ring with zero divisors rather than a field"
),
NumberFieldError::MalformedCoefficient { text } => {
write!(f, "{text:?} is not a rational number")
}
NumberFieldError::NotInvertible => {
write!(f, "zero has no inverse and cannot be divided by")
}
NumberFieldError::FieldMismatch { lhs, rhs } => write!(
f,
"operands live in different number fields: Q[x]/({lhs}) and Q[x]/({rhs})"
),
NumberFieldError::CoefficientCountMismatch { got, degree } => write!(
f,
"element has {got} coefficients but the field has degree {degree}; \
an element is a polynomial of degree < {degree} in the generator"
),
NumberFieldError::CyclotomicOrderOutOfRange { n, max } => write!(
f,
"Q(zeta_{n}) is out of range: n must be at least 1 and phi(n) at most {max}"
),
}
}
}
impl std::error::Error for NumberFieldError {}
impl crate::errors::AlkahestError for NumberFieldError {
fn code(&self) -> &'static str {
match self {
NumberFieldError::EmptyDefiningPolynomial => "E-NUMF-001",
NumberFieldError::DegreeOutOfRange { .. } => "E-NUMF-002",
NumberFieldError::Reducible { .. } => "E-NUMF-003",
NumberFieldError::MalformedCoefficient { .. } => "E-NUMF-004",
NumberFieldError::NotInvertible => "E-NUMF-005",
NumberFieldError::FieldMismatch { .. } => "E-NUMF-006",
NumberFieldError::CoefficientCountMismatch { .. } => "E-NUMF-007",
NumberFieldError::CyclotomicOrderOutOfRange { .. } => "E-NUMF-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)
}
}