use super::{PathAuthority, Role};
#[derive(
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
serde::Deserialize,
serde::Serialize,
strum::AsRefStr,
strum::Display,
strum::EnumCount,
strum::EnumIs,
strum::EnumString,
strum::IntoStaticStr,
strum::VariantNames,
)]
#[serde(rename_all = "kebab-case")]
#[strum(ascii_case_insensitive, serialize_all = "snake_case")]
pub enum PathClass {
Production,
NonCodeDeliverable,
RunArtifact,
NativeState,
}
#[derive(
Clone,
Copy,
Debug,
Eq,
Hash,
Ord,
PartialEq,
PartialOrd,
serde::Deserialize,
serde::Serialize,
strum::AsRefStr,
strum::Display,
strum::EnumCount,
strum::EnumIs,
strum::EnumString,
strum::IntoStaticStr,
strum::VariantNames,
)]
#[serde(rename_all = "kebab-case")]
#[strum(ascii_case_insensitive, serialize_all = "snake_case")]
pub enum PathFactKind {
ExistingFile,
ExistingDirectory,
Missing,
}
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(deny_unknown_fields)]
pub struct TrustedPathFacts {
pub path: PathAuthority,
pub kind: PathFactKind,
pub git_tracked: bool,
pub workspace_member: bool,
pub known_production: bool,
pub known_non_code: bool,
pub run_artifact: bool,
pub native_state: bool,
pub inherited_parent: Option<PathClass>,
pub conflict: bool,
}
#[must_use]
pub const fn classify_trusted_path(facts: &TrustedPathFacts) -> PathClass {
if facts.native_state {
return PathClass::NativeState;
}
if facts.conflict
|| facts.known_production
|| facts.workspace_member
|| (facts.git_tracked && !facts.known_non_code && !facts.run_artifact)
{
return PathClass::Production;
}
if facts.run_artifact {
return PathClass::RunArtifact;
}
if facts.known_non_code {
return PathClass::NonCodeDeliverable;
}
if matches!(facts.kind, PathFactKind::Missing) {
return match facts.inherited_parent {
Some(PathClass::NonCodeDeliverable) => PathClass::NonCodeDeliverable,
Some(PathClass::RunArtifact) => PathClass::RunArtifact,
Some(PathClass::Production | PathClass::NativeState) | None => PathClass::Production,
};
}
PathClass::Production
}
impl Role {
#[must_use]
pub const fn may_write_class(self, class: PathClass) -> bool {
match self {
Self::Coder => matches!(class, PathClass::Production),
Self::Worker => matches!(
class,
PathClass::NonCodeDeliverable | PathClass::RunArtifact
),
Self::Engineer | Self::Conductor => matches!(class, PathClass::RunArtifact),
Self::Auditor | Self::Critic | Self::Discovery | Self::Planter | Self::Shepherd => {
false
}
}
}
}