use crate::Error;
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum CompressionLevel {
Low,
#[default]
Medium,
High,
Max,
}
impl fmt::Display for CompressionLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let value = match self {
Self::Low => "low",
Self::Medium => "medium",
Self::High => "high",
Self::Max => "max",
};
f.write_str(value)
}
}
impl FromStr for CompressionLevel {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_ascii_lowercase().as_str() {
"low" => Ok(Self::Low),
"medium" => Ok(Self::Medium),
"high" => Ok(Self::High),
"max" => Ok(Self::Max),
_ => Err(Error::UnknownCompressionLevel(s.to_string())),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_low() {
assert_eq!("low".parse::<CompressionLevel>().unwrap(), CompressionLevel::Low);
}
#[test]
fn parse_medium() {
assert_eq!("medium".parse::<CompressionLevel>().unwrap(), CompressionLevel::Medium);
}
#[test]
fn parse_high() {
assert_eq!("high".parse::<CompressionLevel>().unwrap(), CompressionLevel::High);
}
#[test]
fn parse_max() {
assert_eq!("max".parse::<CompressionLevel>().unwrap(), CompressionLevel::Max);
}
#[test]
fn parse_case_insensitive() {
assert_eq!("LOW".parse::<CompressionLevel>().unwrap(), CompressionLevel::Low);
assert_eq!("MEDIUM".parse::<CompressionLevel>().unwrap(), CompressionLevel::Medium);
assert_eq!("HIGH".parse::<CompressionLevel>().unwrap(), CompressionLevel::High);
assert_eq!("MAX".parse::<CompressionLevel>().unwrap(), CompressionLevel::Max);
assert_eq!("High".parse::<CompressionLevel>().unwrap(), CompressionLevel::High);
}
#[test]
fn parse_invalid() {
assert!("invalid".parse::<CompressionLevel>().is_err());
}
#[test]
fn parse_empty() {
assert!("".parse::<CompressionLevel>().is_err());
}
#[test]
fn default_is_medium() {
assert_eq!(CompressionLevel::default(), CompressionLevel::Medium);
}
#[test]
fn display_round_trips() {
assert_eq!(CompressionLevel::Low.to_string(), "low");
assert_eq!(CompressionLevel::Medium.to_string(), "medium");
assert_eq!(CompressionLevel::High.to_string(), "high");
assert_eq!(CompressionLevel::Max.to_string(), "max");
}
#[test]
fn display_then_parse_is_identity() {
for level in [
CompressionLevel::Low,
CompressionLevel::Medium,
CompressionLevel::High,
CompressionLevel::Max,
] {
let serialised = level.to_string();
let parsed: CompressionLevel = serialised.parse().unwrap();
assert_eq!(parsed, level);
}
}
}