use crate::poe_standard::{ErrorCode, PoeRecord};
use crate::verifier::types::{PathSegment, Profile, VerifierIssue};
#[must_use]
pub fn profile_at_least(actual: Profile, required: Profile) -> bool {
actual.at_least(required)
}
#[must_use]
pub fn out_of_profile_issues(record: &PoeRecord, profile: Profile) -> Vec<VerifierIssue> {
let mut out = Vec::new();
let has_sigs = record.sigs.as_ref().is_some_and(|s| !s.is_empty());
if !profile_at_least(profile, Profile::Signed) && has_sigs {
out.push(VerifierIssue::new(
ErrorCode::OutOfProfileSkipped,
vec![PathSegment::Key("sigs".to_string())],
format!(
"record carries sigs[] but verifier profile '{}' does not read \
record-level signatures (signed+ profile required)",
profile.as_str()
),
));
}
if !profile_at_least(profile, Profile::Sealed) {
if let Some(items) = &record.items {
for (i, item) in items.iter().enumerate() {
if item.enc.is_some() {
out.push(VerifierIssue::new(
ErrorCode::OutOfProfileSkipped,
vec![
PathSegment::Key("items".to_string()),
PathSegment::Index(i),
PathSegment::Key("enc".to_string()),
],
format!(
"item carries enc envelope but verifier profile '{}' does not \
read sealed envelopes (sealed+ profile required)",
profile.as_str()
),
));
}
}
}
}
out
}
#[must_use]
pub fn detect_conformance_profile(record: &PoeRecord) -> Profile {
let has_sealed = record
.items
.as_ref()
.is_some_and(|items| items.iter().any(|it| it.enc.is_some()));
if has_sealed {
return Profile::Sealed;
}
if record.sigs.as_ref().is_some_and(|s| !s.is_empty()) {
return Profile::Signed;
}
Profile::Core
}