use std::fmt;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum ConformanceLevel {
L0,
L1,
L2,
}
impl ConformanceLevel {
pub fn as_str(&self) -> &'static str {
match self {
Self::L0 => "L0",
Self::L1 => "L1",
Self::L2 => "L2",
}
}
}
impl fmt::Display for ConformanceLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for ConformanceLevel {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"L0" => Ok(Self::L0),
"L1" => Ok(Self::L1),
"L2" => Ok(Self::L2),
_ => Err(format!(
"unknown conformance level '{s}'; expected one of: L0, L1, L2"
)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ordering_l0_lt_l1_lt_l2() {
assert!(ConformanceLevel::L0 < ConformanceLevel::L1);
assert!(ConformanceLevel::L1 < ConformanceLevel::L2);
}
#[test]
fn round_trip() {
for level in [
ConformanceLevel::L0,
ConformanceLevel::L1,
ConformanceLevel::L2,
] {
let s = level.as_str();
let parsed = ConformanceLevel::from_str(s);
assert!(parsed.is_ok());
assert_eq!(parsed.unwrap_or(ConformanceLevel::L0), level);
}
}
#[test]
fn serde_round_trip() {
let level = ConformanceLevel::L1;
let json = serde_json::to_string(&level).unwrap_or_default();
assert_eq!(json, r#""L1""#);
let parsed: ConformanceLevel = serde_json::from_str(&json).unwrap_or(ConformanceLevel::L0);
assert_eq!(parsed, level);
}
}