#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Radical {
Sqrt,
Cbrt,
Qdrt,
}
pub struct RadicalInfo {
pub name: &'static str,
pub glyph: char,
pub latex_index: Option<u8>,
}
pub static RADICAL_NAMES: phf::Map<&'static str, Radical> = phf::phf_map! {
"sqrt" => Radical::Sqrt,
"cbrt" | "sqrt3" => Radical::Cbrt,
"qdrt" | "sqrt4" => Radical::Qdrt,
};
impl Radical {
pub const ALL: [Radical; 3] = [Radical::Sqrt, Radical::Cbrt, Radical::Qdrt];
pub const fn info(self) -> &'static RadicalInfo {
match self {
Radical::Sqrt => &RadicalInfo {
name: "sqrt",
glyph: '√',
latex_index: None,
},
Radical::Cbrt => &RadicalInfo {
name: "cbrt",
glyph: '∛',
latex_index: Some(3),
},
Radical::Qdrt => &RadicalInfo {
name: "qdrt",
glyph: '∜',
latex_index: Some(4),
},
}
}
pub fn of_name(name: &str) -> Option<Radical> {
RADICAL_NAMES.get(name).copied()
}
pub fn name(self) -> &'static str {
self.info().name
}
pub fn glyph(self) -> char {
self.info().glyph
}
pub fn of_glyph(c: char) -> Option<Radical> {
Radical::ALL.into_iter().find(|r| r.glyph() == c)
}
pub fn latex_index(self) -> Option<u8> {
self.info().latex_index
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn radicals_are_a_bijection() {
for r in Radical::ALL {
assert_eq!(Radical::of_glyph(r.glyph()), Some(r));
assert_eq!(Radical::of_name(r.info().name), Some(r));
}
assert_eq!(Radical::of_name("sqrt3"), Some(Radical::Cbrt));
assert_eq!(Radical::of_name("sqrt4"), Some(Radical::Qdrt));
}
}