use crate::error;
use std::{fmt, str::FromStr};
#[repr(u8)]
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Samint {
Ihud = 0,
Senyo = 1,
Makisenyo = 2,
Irob = 3,
Hamus = 4,
Arb = 5,
Kidame = 6,
}
impl Samint {
pub fn next(self) -> Self {
match self {
Samint::Ihud => Samint::Senyo,
Samint::Senyo => Samint::Makisenyo,
Samint::Makisenyo => Samint::Irob,
Samint::Irob => Samint::Hamus,
Samint::Hamus => Samint::Arb,
Samint::Arb => Samint::Kidame,
Samint::Kidame => Samint::Ihud,
}
}
pub fn previous(self) -> Self {
match self {
Samint::Ihud => Samint::Kidame,
Samint::Senyo => Samint::Ihud,
Samint::Makisenyo => Samint::Senyo,
Samint::Irob => Samint::Makisenyo,
Samint::Hamus => Samint::Irob,
Samint::Arb => Samint::Hamus,
Samint::Kidame => Samint::Arb,
}
}
pub fn short_name(&self) -> String {
self.to_string().chars().take(3).collect()
}
}
impl TryFrom<u8> for Samint {
type Error = error::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::Ihud),
1 => Ok(Self::Senyo),
2 => Ok(Self::Makisenyo),
3 => Ok(Self::Irob),
4 => Ok(Self::Hamus),
5 => Ok(Self::Arb),
6 => Ok(Self::Kidame),
oth => Err(error::Error::InvalidRange {
name: "Samint",
given: oth as i32,
min: 0,
max: 6,
}),
}
}
}
impl fmt::Display for Samint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Ihud => "እሑድ",
Self::Senyo => "ሰኞ",
Self::Makisenyo => "ማክሰኞ",
Self::Irob => "ረቡዕ",
Self::Hamus => "ሐሙስ",
Self::Arb => "ዓርብ",
Self::Kidame => "ቅዳሜ",
})
}
}
impl FromStr for Samint {
type Err = error::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let lower = s.to_lowercase();
match lower.as_str() {
"ihud" | "እሑድ" => Ok(Samint::Ihud),
"senyo" | "ሰኞ" => Ok(Samint::Senyo),
"makisenyo" | "ማክሰኞ" => Ok(Samint::Makisenyo),
"irob" | "ረቡዕ" => Ok(Samint::Irob),
"hamus" | "ሐሙስ" => Ok(Samint::Hamus),
"arb" | "ዓርብ" => Ok(Samint::Arb),
"kidame" | "ቅዳሜ" => Ok(Samint::Kidame),
_ => Err(error::Error::InvalidVariant("Samint", lower)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_samint_from_u8() {
let _elet = Samint::try_from(8).unwrap();
}
#[test]
fn test_short_weekday_names() {
let names = ["እሑድ", "ሰኞ", "ማክሰ", "ረቡዕ", "ሐሙስ", "ዓርብ", "ቅዳሜ"];
for e in 0..=6 {
let elet = Samint::try_from(e).expect("should be between 0 and 6");
assert_eq!(elet.short_name(), names[e as usize]);
}
}
#[test]
fn test_from_english_text() -> Result<(), error::Error> {
let amh_week_name = ["እሑድ", "ሰኞ", "ማክሰኞ", "ረቡዕ", "ሐሙስ", "ዓርብ", "ቅዳሜ"];
let eng_week_name = [
"ihud",
"senyo",
"makisenyo",
"irob",
"hamus",
"arb",
"kidame",
];
for (_week_num, (awn, ewn)) in amh_week_name.iter().zip(eng_week_name).enumerate() {
let week_eng = Samint::from_str(awn)?;
let week_amh = Samint::from_str(ewn)?;
assert_eq!(week_amh, week_eng);
}
Ok(())
}
}