use std::fmt;
use clap::ValueEnum;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ValueEnum)]
#[value(rename_all = "kebab-case")]
pub enum GateId {
AdrCitesALiveRule,
AdrFilenameShape,
AdrWordCap,
AgentsDigestSize,
ChapterSizeCap,
ComparisonDatedTables,
ComparisonEscapedPipes,
ComparisonLegend,
ComparisonOneReferencePerCell,
ComparisonVerdictWord,
GateMessageCitesARule,
InstanceManifest,
KiBugzillaReportWidth,
KiFilenameShape,
KiFiling,
KiMechanismWalkthrough,
KiReportBody,
KiRetireWhen,
KiState,
NoPersonalPath,
NoSelfNarration,
ProseStaysUnwrapped,
SpecRequirementParts,
SpecRuleIdUnique,
SpecSizeCap,
SpecVerifyHooksExist,
SuppressionNamesItsCase,
}
impl GateId {
pub const ALL: &'static [Self] = &[
Self::AdrCitesALiveRule,
Self::AdrFilenameShape,
Self::AdrWordCap,
Self::AgentsDigestSize,
Self::ChapterSizeCap,
Self::ComparisonDatedTables,
Self::ComparisonEscapedPipes,
Self::ComparisonLegend,
Self::ComparisonOneReferencePerCell,
Self::ComparisonVerdictWord,
Self::GateMessageCitesARule,
Self::InstanceManifest,
Self::KiBugzillaReportWidth,
Self::KiFilenameShape,
Self::KiFiling,
Self::KiMechanismWalkthrough,
Self::KiReportBody,
Self::KiRetireWhen,
Self::KiState,
Self::NoPersonalPath,
Self::NoSelfNarration,
Self::ProseStaysUnwrapped,
Self::SpecRequirementParts,
Self::SpecRuleIdUnique,
Self::SpecSizeCap,
Self::SpecVerifyHooksExist,
Self::SuppressionNamesItsCase,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::AdrCitesALiveRule => "adr-cites-a-live-rule",
Self::AdrFilenameShape => "adr-filename-shape",
Self::AdrWordCap => "adr-word-cap",
Self::AgentsDigestSize => "agents-digest-size",
Self::ChapterSizeCap => "chapter-size-cap",
Self::ComparisonDatedTables => "comparison-dated-tables",
Self::ComparisonEscapedPipes => "comparison-escaped-pipes",
Self::ComparisonLegend => "comparison-legend",
Self::ComparisonOneReferencePerCell => "comparison-one-reference-per-cell",
Self::ComparisonVerdictWord => "comparison-verdict-word",
Self::GateMessageCitesARule => "gate-message-cites-a-rule",
Self::InstanceManifest => "instance-manifest",
Self::KiBugzillaReportWidth => "ki-bugzilla-report-width",
Self::KiFilenameShape => "ki-filename-shape",
Self::KiFiling => "ki-filing",
Self::KiMechanismWalkthrough => "ki-mechanism-walkthrough",
Self::KiReportBody => "ki-report-body",
Self::KiRetireWhen => "ki-retire-when",
Self::KiState => "ki-state",
Self::NoPersonalPath => "no-personal-path",
Self::NoSelfNarration => "no-self-narration",
Self::ProseStaysUnwrapped => "prose-stays-unwrapped",
Self::SpecRequirementParts => "spec-requirement-parts",
Self::SpecRuleIdUnique => "spec-rule-id-unique",
Self::SpecSizeCap => "spec-size-cap",
Self::SpecVerifyHooksExist => "spec-verify-hooks-exist",
Self::SuppressionNamesItsCase => "suppression-names-its-case",
}
}
}
impl std::str::FromStr for GateId {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::ALL
.iter()
.copied()
.find(|gate| gate.as_str() == s)
.ok_or_else(|| format!("unknown gate: {s}"))
}
}
impl fmt::Display for GateId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_lists_every_variant_once() {
let mut seen = std::collections::BTreeSet::new();
for gate in GateId::ALL {
assert!(seen.insert(gate.as_str()), "{gate} is duplicated");
}
assert_eq!(GateId::ALL.len(), 27);
}
#[test]
fn clap_value_matches_as_str() {
for gate in GateId::ALL {
let value = gate.to_possible_value().unwrap();
assert_eq!(value.get_name(), gate.as_str());
}
}
}