#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CloneClass {
Type1,
Type2,
Type3,
RestrictedSemantic,
}
impl CloneClass {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Type1 => "type-1",
Self::Type2 => "type-2",
Self::Type3 => "type-3",
Self::RestrictedSemantic => "restricted-semantic",
}
}
#[must_use]
pub fn from_name(name: &str) -> Option<Self> {
match name {
"type-1" => Some(Self::Type1),
"type-2" => Some(Self::Type2),
"type-3" => Some(Self::Type3),
"restricted-semantic" => Some(Self::RestrictedSemantic),
_ => None,
}
}
#[must_use]
pub const fn is_exact(self) -> bool {
matches!(self, Self::Type1 | Self::Type2)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CloneScope {
Unit,
Fragment,
}
impl CloneScope {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Unit => "unit",
Self::Fragment => "fragment",
}
}
#[must_use]
pub fn from_name(name: &str) -> Option<Self> {
match name {
"unit" => Some(Self::Unit),
"fragment" => Some(Self::Fragment),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::{CloneClass, CloneScope};
#[test]
fn names_are_the_stable_report_identifiers() {
assert_eq!(CloneClass::Type1.name(), "type-1");
assert_eq!(CloneClass::Type2.name(), "type-2");
assert_eq!(CloneClass::Type3.name(), "type-3");
assert_eq!(CloneClass::RestrictedSemantic.name(), "restricted-semantic");
assert_eq!(CloneScope::Unit.name(), "unit");
assert_eq!(CloneScope::Fragment.name(), "fragment");
}
#[test]
fn a_recorded_name_reads_back_as_what_wrote_it() {
for class in [
CloneClass::Type1,
CloneClass::Type2,
CloneClass::Type3,
CloneClass::RestrictedSemantic,
] {
assert_eq!(CloneClass::from_name(class.name()), Some(class));
}
for scope in [CloneScope::Unit, CloneScope::Fragment] {
assert_eq!(CloneScope::from_name(scope.name()), Some(scope));
}
assert_eq!(CloneClass::from_name("type-4"), None);
assert_eq!(CloneScope::from_name("statement"), None);
}
#[test]
fn ordering_runs_from_exact_to_gapped() {
let mut classes = [
CloneClass::RestrictedSemantic,
CloneClass::Type3,
CloneClass::Type1,
CloneClass::Type2,
];
classes.sort_unstable();
assert_eq!(
classes,
[
CloneClass::Type1,
CloneClass::Type2,
CloneClass::Type3,
CloneClass::RestrictedSemantic,
]
);
}
}