use super::{
ComposedRoads, ContractRefusal, Equivalence, ParityReading, ParitySuite, Road, RoadPairing,
SharedSubstrate, SubstrateRef, SubstrateRefusal, SubstrateRoster, TemporalClaim,
TemporalDemand, TemporalDriveReading, TemporalDriveStanding, TransitionContract,
};
use crate::descriptor::namespaced_reference;
use crate::generate::GeneratedSequences;
use crate::report::{FindingCause, TrialConclusion};
use std::collections::BTreeSet;
namespaced_reference!(SubstrateRef);
impl SubstrateRoster {
pub fn declared(standing: &[SubstrateRef]) -> Result<Self, SubstrateRefusal> {
if standing.is_empty() {
return Err(SubstrateRefusal::EmptyRoster);
}
let mut roster: BTreeSet<SubstrateRef> = BTreeSet::new();
for substrate in standing {
if !roster.insert(*substrate) {
return Err(SubstrateRefusal::DuplicateSubstrate(*substrate));
}
}
Ok(Self { standing: roster })
}
#[must_use]
pub const fn standing(&self) -> &BTreeSet<SubstrateRef> {
&self.standing
}
}
impl<Input, Meaning> ParitySuite<Input, Meaning> {
#[must_use]
pub fn over(
pairing: RoadPairing,
left: Road<Input, Meaning>,
right: Road<Input, Meaning>,
same: Equivalence<Meaning>,
substrate: SharedSubstrate,
) -> Self {
Self {
pairing,
left,
right,
same,
substrate,
}
}
#[must_use]
pub fn fused_versus_separate(
fused: Road<Input, Meaning>,
separate: Road<Input, Meaning>,
same: Equivalence<Meaning>,
substrate: SharedSubstrate,
) -> Self {
Self::over(
RoadPairing::FusedVersusSeparate,
fused,
separate,
same,
substrate,
)
}
#[must_use]
pub fn replay_equivalence(
live: Road<Input, Meaning>,
replayed: Road<Input, Meaning>,
same: Equivalence<Meaning>,
substrate: SharedSubstrate,
) -> Self {
Self::over(
RoadPairing::LiveVersusReplayed,
live,
replayed,
same,
substrate,
)
}
#[must_use]
pub const fn pairing(&self) -> RoadPairing {
self.pairing
}
#[must_use]
pub const fn left(&self) -> Road<Input, Meaning> {
self.left
}
#[must_use]
pub const fn right(&self) -> Road<Input, Meaning> {
self.right
}
#[must_use]
pub const fn same(&self) -> Equivalence<Meaning> {
self.same
}
#[must_use]
pub const fn substrate(&self) -> &SharedSubstrate {
&self.substrate
}
}
impl<'suite, 'input, Input, Meaning> ParityReading<'suite, 'input, Input, Meaning> {
#[must_use]
pub(crate) fn from_run(
suite: &'suite ParitySuite<Input, Meaning>,
input: &'input Input,
left: Meaning,
right: Meaning,
conclusion: TrialConclusion,
) -> Self {
Self {
suite,
input,
left,
right,
conclusion,
}
}
#[must_use]
pub const fn suite(&self) -> &'suite ParitySuite<Input, Meaning> {
self.suite
}
#[must_use]
pub const fn input(&self) -> &'input Input {
self.input
}
#[must_use]
pub const fn left(&self) -> &Meaning {
&self.left
}
#[must_use]
pub const fn right(&self) -> &Meaning {
&self.right
}
#[must_use]
pub const fn conclusion(&self) -> &TrialConclusion {
&self.conclusion
}
}
impl<State> TemporalClaim<State> {
#[must_use]
pub const fn declared(cause: FindingCause, demand: TemporalDemand<State>) -> Self {
Self { cause, demand }
}
#[must_use]
pub const fn cause(&self) -> FindingCause {
self.cause
}
#[must_use]
pub const fn demand(&self) -> &TemporalDemand<State> {
&self.demand
}
}
impl<State, Command> TransitionContract<State, Command> {
pub fn declared(
opening: fn() -> State,
apply: fn(&State, &Command) -> State,
claims: Vec<TemporalClaim<State>>,
) -> Result<Self, ContractRefusal> {
if claims.is_empty() {
return Err(ContractRefusal::NoClaimDeclared);
}
Ok(Self {
opening,
apply,
claims,
})
}
#[must_use]
pub const fn opening(&self) -> fn() -> State {
self.opening
}
#[must_use]
pub const fn apply(&self) -> fn(&State, &Command) -> State {
self.apply
}
#[must_use]
pub fn claims(&self) -> &[TemporalClaim<State>] {
&self.claims
}
}
impl<Command> TemporalDriveReading<Command> {
#[must_use]
pub(crate) const fn from_drive(
generated: GeneratedSequences<Command>,
evaluated: usize,
standing: TemporalDriveStanding,
) -> Self {
Self {
generated,
evaluated,
standing,
}
}
#[must_use]
pub const fn generated(&self) -> &GeneratedSequences<Command> {
&self.generated
}
#[must_use]
pub const fn evaluated(&self) -> usize {
self.evaluated
}
#[must_use]
pub const fn standing(&self) -> &TemporalDriveStanding {
&self.standing
}
}
impl<Entry, Middle, Exit> ComposedRoads<Entry, Middle, Exit> {
#[must_use]
pub const fn wired(
first: Road<Entry, Middle>,
second: Road<Middle, Exit>,
same: Equivalence<Exit>,
) -> Self {
Self {
first,
second,
same,
}
}
#[must_use]
pub const fn first(&self) -> Road<Entry, Middle> {
self.first
}
#[must_use]
pub const fn second(&self) -> Road<Middle, Exit> {
self.second
}
#[must_use]
pub const fn same(&self) -> Equivalence<Exit> {
self.same
}
}