use std::str::FromStr;
use crate::error::KError;
#[inline]
pub fn invalid_choice(field: &str, value: &str, allowed: &[&'static str]) -> KError {
KError::SolveError(format!(
"Invalid {field}: '{value}'. Allowed: {}",
allowed.join(", ")
))
}
macro_rules! simple_kind {
(
$(#[$m:meta])*
$vis:vis enum $Name:ident { $($v:ident => $s:literal),+ $(,)? }
) => {
$(#[$m])*
$vis enum $Name { $( $v ),+ }
impl $Name {
pub const fn allowed() -> &'static [&'static str] {
&[ $( $s ),+ ]
}
}
impl FromStr for $Name {
type Err = KError;
fn from_str(raw: &str) -> Result<Self, Self::Err> {
let s = raw.to_ascii_lowercase();
match s.as_str() {
$( $s => Ok(Self::$v), )+
other => {
let name_lower = stringify!($Name).to_ascii_lowercase();
Err(invalid_choice(name_lower.as_str(), other, Self::allowed()))
},
}
}
}
};
}
simple_kind! {
pub enum ReorderKind { None => "none", Colamd => "colamd", Amd => "amd", Rcm => "rcm", CuthillMckee => "cuthill_mckee" }
}
simple_kind! {
pub enum ScalingKind { None => "none", Diagonal => "diagonal", Symmetric => "symmetric" }
}
simple_kind! {
pub enum IluTypeKind {
Ilu0 => "ilu0",
Iluk => "iluk",
Ilut => "ilut",
Milu0 => "milu0",
BlockJacobi => "block_jacobi",
GmresIluk => "gmres_iluk",
GmresIlut => "gmres_ilut",
}
}
simple_kind! {
pub enum IluReorderKind { None => "none", Rcm => "rcm", Amd => "amd", Natural => "natural" }
}
simple_kind! {
pub enum IluTriSolveKind { Exact => "exact", Iterative => "iterative" }
}
simple_kind! {
pub enum IluParFactorKind { None => "none", Block => "block", ParILU => "parilu" }
}
simple_kind! {
pub enum AmgCoarsenKind { Rs => "rs", Hmis => "hmis", Pmis => "pmis", Falgout => "falgout" }
}
simple_kind! {
pub enum AmgInterpKind {
Classical => "classical",
Direct => "direct",
Multipass => "multipass",
Extended => "extended",
Standard => "standard",
He => "he",
}
}
simple_kind! {
pub enum AmgRelaxKind {
Jacobi => "jacobi",
Gs => "gs",
Gsr => "gsr",
Sgs => "sgs",
Hgs => "hgs",
L1Jacobi => "l1jacobi",
Chebyshev => "chebyshev",
ChebyshevSafe => "chebyshev_safe",
SafeguardedGs => "safegs",
Ilu0 => "ilu0",
Ras => "ras",
}
}
simple_kind! {
pub enum AsmBlockSolverKind { Ludense => "ludense", Csr => "csr" }
}
simple_kind! {
pub enum AsmModeKind { Asm => "asm", Ras => "ras" }
}
simple_kind! {
pub enum SorMatSideKind {
Lower => "lower",
Upper => "upper",
Symmetric => "symmetric",
Eisenstat => "eisenstat",
}
}