#![forbid(unsafe_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StandardEdition {
Iso22057_2022,
}
impl StandardEdition {
pub const CURRENT: Self = Self::Iso22057_2022;
#[must_use]
pub const fn designation(self) -> &'static str {
match self {
Self::Iso22057_2022 => "ISO 22057:2022",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum InformationModuleGroup {
Product,
ConstructionProcess,
Use,
EndOfLife,
BeyondSystemBoundary,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum InformationModule {
A1,
A2,
A3,
A1ToA3,
A4,
A5,
B1,
B2,
B3,
B4,
B5,
B6,
B7,
C1,
C2,
C3,
C4,
D,
}
impl InformationModule {
pub const ALL: [Self; 18] = [
Self::A1,
Self::A2,
Self::A3,
Self::A1ToA3,
Self::A4,
Self::A5,
Self::B1,
Self::B2,
Self::B3,
Self::B4,
Self::B5,
Self::B6,
Self::B7,
Self::C1,
Self::C2,
Self::C3,
Self::C4,
Self::D,
];
#[must_use]
pub const fn code(self) -> &'static str {
match self {
Self::A1 => "A1",
Self::A2 => "A2",
Self::A3 => "A3",
Self::A1ToA3 => "A1-A3",
Self::A4 => "A4",
Self::A5 => "A5",
Self::B1 => "B1",
Self::B2 => "B2",
Self::B3 => "B3",
Self::B4 => "B4",
Self::B5 => "B5",
Self::B6 => "B6",
Self::B7 => "B7",
Self::C1 => "C1",
Self::C2 => "C2",
Self::C3 => "C3",
Self::C4 => "C4",
Self::D => "D",
}
}
#[must_use]
pub const fn from_code(code: &str) -> Option<Self> {
match code.as_bytes() {
b"A1" => Some(Self::A1),
b"A2" => Some(Self::A2),
b"A3" => Some(Self::A3),
b"A1-A3" => Some(Self::A1ToA3),
b"A4" => Some(Self::A4),
b"A5" => Some(Self::A5),
b"B1" => Some(Self::B1),
b"B2" => Some(Self::B2),
b"B3" => Some(Self::B3),
b"B4" => Some(Self::B4),
b"B5" => Some(Self::B5),
b"B6" => Some(Self::B6),
b"B7" => Some(Self::B7),
b"C1" => Some(Self::C1),
b"C2" => Some(Self::C2),
b"C3" => Some(Self::C3),
b"C4" => Some(Self::C4),
b"D" => Some(Self::D),
_ => None,
}
}
#[must_use]
pub const fn group(self) -> InformationModuleGroup {
match self {
Self::A1 | Self::A2 | Self::A3 | Self::A1ToA3 => InformationModuleGroup::Product,
Self::A4 | Self::A5 => InformationModuleGroup::ConstructionProcess,
Self::B1 | Self::B2 | Self::B3 | Self::B4 | Self::B5 | Self::B6 | Self::B7 => {
InformationModuleGroup::Use
}
Self::C1 | Self::C2 | Self::C3 | Self::C4 => InformationModuleGroup::EndOfLife,
Self::D => InformationModuleGroup::BeyondSystemBoundary,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn current_edition_has_the_normative_designation() {
assert_eq!(StandardEdition::CURRENT.designation(), "ISO 22057:2022");
}
#[test]
fn lifecycle_modules_are_complete_and_round_trip() {
const EXPECTED_CODES: [&str; 18] = [
"A1", "A2", "A3", "A1-A3", "A4", "A5", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "C1",
"C2", "C3", "C4", "D",
];
assert_eq!(
InformationModule::ALL.map(InformationModule::code),
EXPECTED_CODES
);
for module in InformationModule::ALL {
assert_eq!(InformationModule::from_code(module.code()), Some(module));
}
}
#[test]
fn lifecycle_modules_map_to_their_groups() {
assert_eq!(
InformationModule::A1.group(),
InformationModuleGroup::Product
);
assert_eq!(
InformationModule::A3.group(),
InformationModuleGroup::Product
);
assert_eq!(
InformationModule::A1ToA3.group(),
InformationModuleGroup::Product
);
assert_eq!(
InformationModule::A4.group(),
InformationModuleGroup::ConstructionProcess
);
assert_eq!(InformationModule::B7.group(), InformationModuleGroup::Use);
assert_eq!(
InformationModule::C4.group(),
InformationModuleGroup::EndOfLife
);
assert_eq!(
InformationModule::D.group(),
InformationModuleGroup::BeyondSystemBoundary
);
}
#[test]
fn unknown_module_codes_are_rejected() {
assert_eq!(InformationModule::from_code("A0"), None);
assert_eq!(InformationModule::from_code("a1"), None);
assert_eq!(InformationModule::from_code(""), None);
}
}