use super::Error;
#[cfg(feature = "serde")]
use serde::Serialize;
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum FileSequence {
Batch(u8),
DayPortion(u8),
#[default]
DayCourse,
}
impl std::str::FromStr for FileSequence {
type Err = Error;
fn from_str(content: &str) -> Result<Self, Self::Err> {
let chars = content.chars().nth(0).unwrap();
if chars == '0' {
Ok(Self::DayCourse)
} else if chars.is_ascii_alphabetic() {
let value = chars as u32 - 97;
if value < 24 {
Ok(Self::DayPortion(value as u8))
} else {
Err(Error::InvalidFileSequence)
}
} else {
let batch_id = content
.parse::<u8>()
.map_err(|_| Error::InvalidFileSequence)?;
Ok(Self::Batch(batch_id))
}
}
}
#[cfg(test)]
mod test {
use super::FileSequence;
use std::str::FromStr;
#[test]
fn file_sequence_parsing() {
for (desc, expected) in [
("a", FileSequence::DayPortion(0)),
("b", FileSequence::DayPortion(1)),
("c", FileSequence::DayPortion(2)),
("d", FileSequence::DayPortion(3)),
("e", FileSequence::DayPortion(4)),
("u", FileSequence::DayPortion(20)),
("v", FileSequence::DayPortion(21)),
("w", FileSequence::DayPortion(22)),
("x", FileSequence::DayPortion(23)),
("0", FileSequence::DayCourse),
("1", FileSequence::Batch(1)),
("2", FileSequence::Batch(2)),
("10", FileSequence::Batch(10)),
] {
let seq = FileSequence::from_str(desc).unwrap_or_else(|_| {
panic!("failed to parse \"{}\"", desc);
});
assert_eq!(seq, expected);
}
assert!(
FileSequence::from_str("z").is_err(),
"this file sequence is invalid"
);
}
}