use crate::authority::AuthorityHash;
use crate::densor::DensorKind;
use crate::errors::RuntimeError;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DensorEntry {
pub id: String,
pub kind: DensorKind,
pub evidence_hash: [u8; 32],
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DensorManifest {
pub pipeline_id: String,
pub densors: Vec<DensorEntry>,
pub authorities: Vec<AuthorityHash>,
}
impl DensorManifest {
pub fn validate(&self) -> Result<(), RuntimeError> {
if self.pipeline_id.trim().is_empty() {
return Err(RuntimeError::ManifestInvalid("empty pipeline_id".into()));
}
if self.authorities.is_empty() {
return Err(RuntimeError::ManifestInvalid(
"no frozen authorities (a run needs an authority anchor)".into(),
));
}
let mut seen = std::collections::BTreeSet::new();
for d in &self.densors {
if d.id.trim().is_empty() {
return Err(RuntimeError::ManifestInvalid(
"a densor entry has an empty id".into(),
));
}
if !seen.insert(d.id.as_str()) {
return Err(RuntimeError::ManifestInvalid(format!(
"duplicate densor id '{}'",
d.id
)));
}
}
Ok(())
}
pub fn permits_authority(&self, authority: &AuthorityHash) -> bool {
self.authorities
.iter()
.any(|a| a.name == authority.name && a.hash == authority.hash)
}
}