use super::{Accounted, BindError, Expansion};
use crate::closure::{Closure, PartitionCargo, PartitionedEmission};
use crate::explanation::View;
use crate::identity::{self, ClosedExpansionId, Provenance, Transcript, encode_bytes};
use crate::kind::{Destination, DispositionSet, Kind, KindSet};
use crate::plan::Plan;
use crate::render::RenderedUnit;
impl<K: Kind> Expansion<K> {
pub fn bound(
plan: Plan<K>,
closure: Closure<K::Role>,
explanation: View<K>,
) -> Result<Self, BindError> {
let planned = plan.identity();
let proved = closure.plan();
if planned != proved {
return Err(BindError::ClosureProvedAgainstAnotherPlan { planned, proved });
}
let answered_over_plan = explanation.plan();
if planned != answered_over_plan {
return Err(BindError::ExplanationAnsweredOverAnotherPlan {
planned,
answered: answered_over_plan,
});
}
let anchor = closure.identity();
let answered_over_closure = explanation.closure();
if anchor != answered_over_closure {
return Err(BindError::ExplanationAnsweredOverAnotherClosure {
proved: anchor,
answered: answered_over_closure,
});
}
let mut content = Vec::new();
encode_bytes(planned.as_bytes(), &mut content);
encode_bytes(explanation.identity().as_bytes(), &mut content);
let (derived, provenance) = ClosedExpansionId::derived_with_provenance(
Transcript::under_projection(identity::Role::ClosedExpansion, &anchor, &content, 0),
);
Ok(Self {
identity: derived,
provenance,
plan,
closure,
explanation,
})
}
#[must_use]
pub const fn identity(&self) -> ClosedExpansionId {
self.identity
}
#[must_use]
pub const fn provenance(&self) -> &Provenance {
&self.provenance
}
pub const fn plan(&self) -> &Plan<K> {
&self.plan
}
pub const fn closure(&self) -> &Closure<K::Role> {
&self.closure
}
pub const fn explain(&self) -> &View<K> {
&self.explanation
}
pub const fn emission(&self) -> &PartitionedEmission {
self.closure.emission()
}
pub const fn emit(&self) -> &PartitionCargo {
self.emission().declaration_site()
}
pub const fn test_carrier(&self) -> &PartitionCargo {
self.emission().test_carrier()
}
pub const fn bench_carrier(&self) -> &PartitionCargo {
self.emission().bench_carrier()
}
pub fn published(&self) -> impl Iterator<Item = &RenderedUnit<K::Role>> {
self.closure
.rendered()
.units_to(Destination::PublicationArtifact)
}
}
impl<K: Kind, Set: KindSet> Accounted<K, Set> {
pub const fn seated(expansion: Expansion<K>, dispositions: DispositionSet<Set>) -> Self {
Self {
expansion,
dispositions,
}
}
pub const fn expansion(&self) -> &Expansion<K> {
&self.expansion
}
pub const fn dispositions(&self) -> &DispositionSet<Set> {
&self.dispositions
}
}