use serde::{Deserialize, Serialize};
use super::schema::{ReviewScope, SandboxKind};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum DepPinnedState {
AllPinned,
Unpinned {
unpinned_deps: Vec<String>,
},
NotInManifest {
crate_name: String,
},
}
impl DepPinnedState {
#[must_use]
pub const fn is_pass(&self) -> bool {
matches!(self, Self::AllPinned)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum DepAttestedState {
Attested {
review_scope: ReviewScope,
},
AttestedWithoutReviewableArtifact,
SidecarMissing,
SidecarMalformed {
error: String,
},
AttestationStale {
attested_version: String,
requested_version: String,
},
}
impl DepAttestedState {
#[must_use]
pub const fn is_pass(&self) -> bool {
matches!(self, Self::Attested { .. })
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum MaintainerState {
Unchanged,
Changed {
added: Vec<String>,
removed: Vec<String>,
},
SnapshotMissing,
CratesIoQueryUnavailable,
}
impl MaintainerState {
#[must_use]
pub const fn is_pass(&self) -> bool {
matches!(self, Self::Unchanged)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum ContentHashState {
Matches,
Mismatch {
recorded: String,
current: String,
},
NoAttestation,
CrateNotInLockfile {
crate_name: String,
},
SidecarMalformed {
error: String,
},
}
impl ContentHashState {
#[must_use]
pub const fn is_pass(&self) -> bool {
matches!(self, Self::Matches)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum SandboxState {
Clean {
sandbox_kind: SandboxKind,
},
Violation {
sandbox_kind: SandboxKind,
details: String,
},
ToolingNotYetAvailable {
sandbox_kind: SandboxKind,
},
}
impl SandboxState {
#[must_use]
pub const fn is_pass(&self) -> bool {
matches!(self, Self::Clean { .. })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pinned_state_predicate_logic() {
assert!(DepPinnedState::AllPinned.is_pass());
assert!(!DepPinnedState::Unpinned {
unpinned_deps: vec!["serde".to_string()],
}
.is_pass());
assert!(!DepPinnedState::NotInManifest {
crate_name: "missing".to_string(),
}
.is_pass());
}
#[test]
fn dep_attested_state_predicate_logic() {
assert!(DepAttestedState::Attested {
review_scope: ReviewScope::Full,
}
.is_pass());
assert!(!DepAttestedState::AttestedWithoutReviewableArtifact.is_pass());
assert!(!DepAttestedState::SidecarMissing.is_pass());
}
#[test]
fn content_hash_state_predicate_logic() {
assert!(ContentHashState::Matches.is_pass());
assert!(!ContentHashState::Mismatch {
recorded: "a".to_string(),
current: "b".to_string(),
}
.is_pass());
assert!(!ContentHashState::NoAttestation.is_pass());
}
#[test]
fn sandbox_state_v02_returns_tooling_unavailable() {
let s = SandboxState::ToolingNotYetAvailable {
sandbox_kind: SandboxKind::Build,
};
assert!(!s.is_pass());
}
}