use crate::descriptor::types::{
CheckRef, DERIVED_REVISION_DOMAIN, DerivedRevision, ExecutableAttachment, RevisionBinding,
RevisionPosture, SubjectRoute,
};
use crate::identity::ContentAddress;
impl RevisionPosture {
#[must_use]
pub const fn meet(self, other: Self) -> Self {
match (self, other) {
(Self::Derived, Self::Derived) => Self::Derived,
(Self::Derived | Self::Declared, Self::Declared) | (Self::Declared, Self::Derived) => {
Self::Declared
}
(Self::Untracked, Self::Derived | Self::Declared | Self::Untracked)
| (Self::Derived | Self::Declared, Self::Untracked) => Self::Untracked,
}
}
}
impl DerivedRevision {
#[must_use]
pub fn from_material(material: &[u8]) -> Self {
Self {
revision: ContentAddress::derived(DERIVED_REVISION_DOMAIN, material),
}
}
#[must_use]
pub const fn revision(self) -> ContentAddress {
self.revision
}
}
impl RevisionBinding {
#[must_use]
pub const fn derived(evidence: DerivedRevision) -> Self {
Self {
revision: evidence.revision(),
posture: RevisionPosture::Derived,
}
}
#[must_use]
pub const fn declared(revision: ContentAddress) -> Self {
Self {
revision,
posture: RevisionPosture::Declared,
}
}
#[must_use]
pub const fn untracked(revision: ContentAddress) -> Self {
Self {
revision,
posture: RevisionPosture::Untracked,
}
}
#[must_use]
pub const fn revision(self) -> ContentAddress {
self.revision
}
#[must_use]
pub const fn posture(self) -> RevisionPosture {
self.posture
}
}
impl<Invocation, Conclusion> ExecutableAttachment<Invocation, Conclusion> {
#[must_use]
pub const fn attached(
subject: SubjectRoute,
check: CheckRef,
subject_revision: RevisionBinding,
check_revision: RevisionBinding,
call: fn(&Invocation) -> Conclusion,
) -> Self {
Self {
subject,
check,
subject_revision,
check_revision,
call,
}
}
#[must_use]
pub const fn subject(&self) -> SubjectRoute {
self.subject
}
#[must_use]
pub const fn check(&self) -> CheckRef {
self.check
}
#[must_use]
pub const fn subject_revision(&self) -> RevisionBinding {
self.subject_revision
}
#[must_use]
pub const fn check_revision(&self) -> RevisionBinding {
self.check_revision
}
#[must_use]
pub const fn posture(&self) -> RevisionPosture {
self.subject_revision
.posture()
.meet(self.check_revision.posture())
}
#[must_use]
pub const fn call(&self) -> fn(&Invocation) -> Conclusion {
self.call
}
#[must_use]
pub fn conclude(&self, invocation: &Invocation) -> Conclusion {
(self.call)(invocation)
}
}
impl<Invocation, Conclusion> Clone for ExecutableAttachment<Invocation, Conclusion> {
fn clone(&self) -> Self {
Self {
subject: self.subject,
check: self.check,
subject_revision: self.subject_revision,
check_revision: self.check_revision,
call: self.call,
}
}
}