#![forbid(unsafe_code)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Stage {
SecurePairing,
ReadCommissioningInfo,
ArmFailsafe,
ConfigRegulatory,
SendPaiCertRequest,
SendDacCertRequest,
SendAttestationRequest,
AttestationVerification,
SendOpCertSigningRequest,
ValidateCsr,
GenerateNocChain,
SendTrustedRootCert,
SendNoc,
ReadNetworkCommissioningInfo,
NetworkSetup,
FailsafeBeforeNetworkEnable,
NetworkEnable,
EvictPreviousCaseSessions,
FindOperationalForComplete,
SendComplete,
Cleanup,
Failed,
}
#[allow(dead_code)]
#[allow(unreachable_pub)]
#[must_use]
pub fn next_stage(current: Stage) -> Option<Stage> {
Some(match current {
Stage::SecurePairing => Stage::ReadCommissioningInfo,
Stage::ReadCommissioningInfo => Stage::ArmFailsafe,
Stage::ArmFailsafe => Stage::ConfigRegulatory,
Stage::ConfigRegulatory => Stage::SendPaiCertRequest,
Stage::SendPaiCertRequest => Stage::SendDacCertRequest,
Stage::SendDacCertRequest => Stage::SendAttestationRequest,
Stage::SendAttestationRequest => Stage::AttestationVerification,
Stage::AttestationVerification => Stage::SendOpCertSigningRequest,
Stage::SendOpCertSigningRequest => Stage::ValidateCsr,
Stage::ValidateCsr => Stage::GenerateNocChain,
Stage::GenerateNocChain => Stage::SendTrustedRootCert,
Stage::SendTrustedRootCert => Stage::SendNoc,
Stage::SendNoc => Stage::ReadNetworkCommissioningInfo,
Stage::ReadNetworkCommissioningInfo => Stage::NetworkSetup,
Stage::NetworkSetup => Stage::FailsafeBeforeNetworkEnable,
Stage::FailsafeBeforeNetworkEnable => Stage::NetworkEnable,
Stage::NetworkEnable => Stage::EvictPreviousCaseSessions,
Stage::EvictPreviousCaseSessions => Stage::FindOperationalForComplete,
Stage::FindOperationalForComplete => Stage::SendComplete,
Stage::SendComplete => Stage::Cleanup,
Stage::Cleanup | Stage::Failed => return None,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn happy_path_advances_through_all_stages() {
#![allow(clippy::unwrap_used)]
let expected = [
Stage::SecurePairing,
Stage::ReadCommissioningInfo,
Stage::ArmFailsafe,
Stage::ConfigRegulatory,
Stage::SendPaiCertRequest,
Stage::SendDacCertRequest,
Stage::SendAttestationRequest,
Stage::AttestationVerification,
Stage::SendOpCertSigningRequest,
Stage::ValidateCsr,
Stage::GenerateNocChain,
Stage::SendTrustedRootCert,
Stage::SendNoc,
Stage::ReadNetworkCommissioningInfo,
Stage::NetworkSetup,
Stage::FailsafeBeforeNetworkEnable,
Stage::NetworkEnable,
Stage::EvictPreviousCaseSessions,
Stage::FindOperationalForComplete,
Stage::SendComplete,
Stage::Cleanup,
];
for pair in expected.windows(2) {
assert_eq!(
next_stage(pair[0]),
Some(pair[1]),
"next_stage({:?}) should be Some({:?})",
pair[0],
pair[1],
);
}
assert_eq!(next_stage(Stage::Cleanup), None, "Cleanup is terminal");
assert_eq!(next_stage(Stage::Failed), None, "Failed is terminal");
}
}