#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ModuleInfoField {
Binary,
Version,
ModuleVersion,
Maintainer,
Name,
Type,
Repo,
Branch,
Hash,
Copyright,
Os,
OsVersion,
}
impl ModuleInfoField {
pub fn to_symbol_name(&self) -> &'static str {
match self {
ModuleInfoField::Binary => "module_info_binary",
ModuleInfoField::Version => "module_info_version",
ModuleInfoField::ModuleVersion => "module_info_moduleVersion",
ModuleInfoField::Maintainer => "module_info_maintainer",
ModuleInfoField::Name => "module_info_name",
ModuleInfoField::Type => "module_info_type",
ModuleInfoField::Repo => "module_info_repo",
ModuleInfoField::Branch => "module_info_branch",
ModuleInfoField::Hash => "module_info_hash",
ModuleInfoField::Copyright => "module_info_copyright",
ModuleInfoField::Os => "module_info_os",
ModuleInfoField::OsVersion => "module_info_osVersion",
}
}
pub fn to_key(&self) -> &'static str {
match self {
ModuleInfoField::Binary => "binary",
ModuleInfoField::Version => "version",
ModuleInfoField::ModuleVersion => "moduleVersion",
ModuleInfoField::Maintainer => "maintainer",
ModuleInfoField::Name => "name",
ModuleInfoField::Type => "type",
ModuleInfoField::Repo => "repo",
ModuleInfoField::Branch => "branch",
ModuleInfoField::Hash => "hash",
ModuleInfoField::Copyright => "copyright",
ModuleInfoField::Os => "os",
ModuleInfoField::OsVersion => "osVersion",
}
}
pub const ALL: &'static [ModuleInfoField] = &[
ModuleInfoField::Binary,
ModuleInfoField::Version,
ModuleInfoField::ModuleVersion,
ModuleInfoField::Maintainer,
ModuleInfoField::Name,
ModuleInfoField::Type,
ModuleInfoField::Repo,
ModuleInfoField::Branch,
ModuleInfoField::Hash,
ModuleInfoField::Copyright,
ModuleInfoField::Os,
ModuleInfoField::OsVersion,
];
pub const fn count() -> usize {
Self::ALL.len()
}
}
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use super::*;
#[test]
fn count_matches_all_length() {
assert_eq!(ModuleInfoField::count(), ModuleInfoField::ALL.len());
}
#[test]
fn all_has_unique_symbol_names_and_keys() {
let symbols: HashSet<&str> = ModuleInfoField::ALL
.iter()
.map(|f| f.to_symbol_name())
.collect();
assert_eq!(
symbols.len(),
ModuleInfoField::ALL.len(),
"ModuleInfoField::ALL has duplicate entries (by symbol name)"
);
let keys: HashSet<&str> = ModuleInfoField::ALL.iter().map(|f| f.to_key()).collect();
assert_eq!(
keys.len(),
ModuleInfoField::ALL.len(),
"ModuleInfoField::ALL has duplicate entries (by HashMap key)"
);
}
#[test]
fn every_variant_is_listed_in_all() {
const EXPECTED_VARIANT_COUNT: usize = 12;
fn canonical_key(f: ModuleInfoField) -> &'static str {
match f {
ModuleInfoField::Binary => "binary",
ModuleInfoField::Version => "version",
ModuleInfoField::ModuleVersion => "moduleVersion",
ModuleInfoField::Maintainer => "maintainer",
ModuleInfoField::Name => "name",
ModuleInfoField::Type => "type",
ModuleInfoField::Repo => "repo",
ModuleInfoField::Branch => "branch",
ModuleInfoField::Hash => "hash",
ModuleInfoField::Copyright => "copyright",
ModuleInfoField::Os => "os",
ModuleInfoField::OsVersion => "osVersion",
}
}
assert_eq!(
ModuleInfoField::ALL.len(),
EXPECTED_VARIANT_COUNT,
"ModuleInfoField::ALL length changed: if you added a variant, \
extend ALL and bump EXPECTED_VARIANT_COUNT; if you removed one, \
drop it from ALL and bump EXPECTED_VARIANT_COUNT down"
);
for f in ModuleInfoField::ALL {
assert_eq!(f.to_key(), canonical_key(*f));
}
}
}