#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Level {
L0,
L1,
L2,
L3,
L4,
}
impl Level {
pub const ALL: [Level; 5] = [Level::L0, Level::L1, Level::L2, Level::L3, Level::L4];
#[must_use]
pub const fn id(self) -> &'static str {
match self {
Level::L0 => "l0",
Level::L1 => "l1",
Level::L2 => "l2",
Level::L3 => "l3",
Level::L4 => "l4",
}
}
#[must_use]
pub const fn crate_name(self) -> &'static str {
match self {
Level::L0 => "vize_l0",
Level::L1 => "vize_l1",
Level::L2 => "vize_l2",
Level::L3 => "vize_l3",
Level::L4 => "vize_l4",
}
}
#[must_use]
pub fn from_id(id: &str) -> Option<Self> {
Self::ALL.into_iter().find(|level| level.id() == id)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Conversion {
pub from: Level,
pub to: Level,
pub crate_name: &'static str,
}
pub const CONVERSIONS: &[Conversion] = &[
Conversion {
from: Level::L1,
to: Level::L2,
crate_name: "vize_l1_to_l2",
},
Conversion {
from: Level::L2,
to: Level::L3,
crate_name: "vize_l2_to_l3",
},
];
#[cfg(test)]
mod tests {
use super::{CONVERSIONS, Level};
#[test]
fn ids_round_trip() {
let expected = [
(Level::L0, "l0", "vize_l0"),
(Level::L1, "l1", "vize_l1"),
(Level::L2, "l2", "vize_l2"),
(Level::L3, "l3", "vize_l3"),
(Level::L4, "l4", "vize_l4"),
];
for (level, id, crate_name) in expected {
assert_eq!(level.id(), id);
assert_eq!(level.crate_name(), crate_name);
assert_eq!(Level::from_id(id), Some(level));
}
assert_eq!(Level::from_id("s2"), None);
}
#[test]
fn conversions_join_adjacent_levels() {
for conversion in CONVERSIONS {
let to = conversion
.crate_name
.strip_prefix("vize_")
.and_then(|rest| rest.strip_prefix(conversion.from.id()))
.and_then(|rest| rest.strip_prefix("_to_"));
assert_eq!(to, Some(conversion.to.id()));
}
}
}