use crate::{
Behavior, BirthProtocol, BirthProtocolProduct, ChildDelivery, ChildInput, ComposedEvent,
Delivery, EndpointAddress, EstablishedDelivery, InjectEvent, Inside, NoBirthProtocols,
Protocol,
};
use core::future::Future;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ItemSettlement<Item, Accepted, Rejection, Prerequisite> {
Accepted(Accepted),
Rejected { item: Item, reason: Rejection },
Blocked {
item: Item,
prerequisite: Prerequisite,
},
Corrupt { item: Item, fault: InterpreterFault },
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SettledItem<Item, Settlement> {
Attempted(Settlement),
Unattempted(Item),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Interpretation<Settlement> {
Complete(Settlement),
Corrupt(Settlement),
}
impl<Settlement> Interpretation<Settlement> {
#[must_use]
pub fn map<Mapped>(self, map: impl FnOnce(Settlement) -> Mapped) -> Interpretation<Mapped> {
match self {
Self::Complete(settlement) => Interpretation::Complete(map(settlement)),
Self::Corrupt(settlement) => Interpretation::Corrupt(map(settlement)),
}
}
#[must_use]
pub fn into_settlement(self) -> Settlement {
match self {
Self::Complete(settlement) | Self::Corrupt(settlement) => settlement,
}
}
}
#[doc(hidden)]
pub async fn settle_in_order<Interpreter, RootEvent, Path, Earlier, Later>(
earlier: Earlier,
later: Later,
interpreter: &mut Interpreter,
) -> Interpretation<(Earlier::Settlements, Later::Settlements)>
where
Interpreter: Send,
Earlier: InterpretSends<Interpreter, RootEvent, Path>,
Later: InterpretSends<Interpreter, RootEvent, Path>,
{
let earlier = match earlier.interpret(interpreter).await {
Interpretation::Complete(earlier) => earlier,
Interpretation::Corrupt(earlier) => {
return Interpretation::Corrupt((earlier, later.unattempted()));
}
};
later
.interpret(interpreter)
.await
.map(|later| (earlier, later))
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SettlementStatus {
Accepted,
Rejected,
Corrupt,
}
impl SettlementStatus {
#[must_use]
pub const fn combine(self, later: Self) -> Self {
match (self, later) {
(Self::Corrupt, _) | (_, Self::Corrupt) => Self::Corrupt,
(Self::Rejected, _) | (_, Self::Rejected) => Self::Rejected,
(Self::Accepted, Self::Accepted) => Self::Accepted,
}
}
}
pub trait ClassifySettlement {
fn settlement_status(&self) -> SettlementStatus;
}
impl<Item, Accepted, Rejection, Prerequisite> ClassifySettlement
for ItemSettlement<Item, Accepted, Rejection, Prerequisite>
{
fn settlement_status(&self) -> SettlementStatus {
match self {
Self::Accepted(_) => SettlementStatus::Accepted,
Self::Rejected { .. } | Self::Blocked { .. } => SettlementStatus::Rejected,
Self::Corrupt { .. } => SettlementStatus::Corrupt,
}
}
}
impl<Item, Settlement> ClassifySettlement for SettledItem<Item, Settlement>
where
Settlement: ClassifySettlement,
{
fn settlement_status(&self) -> SettlementStatus {
match self {
Self::Attempted(settlement) => settlement.settlement_status(),
Self::Unattempted(_) => SettlementStatus::Corrupt,
}
}
}
impl<Settlement> ClassifySettlement for Interpretation<Settlement>
where
Settlement: ClassifySettlement,
{
fn settlement_status(&self) -> SettlementStatus {
match self {
Self::Complete(settlement) => settlement.settlement_status(),
Self::Corrupt(_) => SettlementStatus::Corrupt,
}
}
}
impl<Settlement> ClassifySettlement for Vec<Settlement>
where
Settlement: ClassifySettlement,
{
fn settlement_status(&self) -> SettlementStatus {
let mut status = SettlementStatus::Accepted;
for settlement in self {
status = status.combine(settlement.settlement_status());
}
status
}
}
impl ClassifySettlement for crate::Never {
fn settlement_status(&self) -> SettlementStatus {
match *self {}
}
}
pub trait ActionItem: Sized + Send {
type Accepted: Send;
type Rejection: Send;
type Prerequisite: Send;
}
pub type ActionItemResult<
Item,
Accepted = <Item as ActionItem>::Accepted,
Rejection = <Item as ActionItem>::Rejection,
Prerequisite = <Item as ActionItem>::Prerequisite,
> = SettledItem<Item, ItemSettlement<Item, Accepted, Rejection, Prerequisite>>;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum InterpreterFault {
MissingCapability,
CorruptTraversal,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ParentReportReason {
ClosedParentControlLane,
}
pub trait InterpretItem<Item, RootEvent, Path>: Send
where
Item: ActionItem,
{
fn interpret_item(
&mut self,
item: Item,
) -> impl Future<
Output = ItemSettlement<Item, Item::Accepted, Item::Rejection, Item::Prerequisite>,
> + Send;
}
pub trait SendSettlements: Sized {
type Settlements: Send + ClassifySettlement;
fn unattempted(self) -> Self::Settlements;
}
pub trait InterpretSends<Interpreter, RootEvent, Path>: SendSettlements + Send {
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send;
}
pub enum Own {}
pub trait SendInput<Input, Path> {
fn emit(&mut self, input: Input);
}
pub trait SendEffects: Sized {
fn empty() -> Self;
fn append(&mut self, other: Self);
#[must_use]
fn combine(mut self, other: Self) -> Self {
self.append(other);
self
}
fn send<Input, Path>(&mut self, input: Input)
where
Self: SendInput<Input, Path>,
{
<Self as SendInput<Input, Path>>::emit(self, input);
}
#[must_use]
fn sending<Input, Path>(input: Input) -> Self
where
Self: SendInput<Input, Path>,
{
let mut sends = Self::empty();
sends.send(input);
sends
}
}
pub trait LogicalDeliveryProtocols: SendEffects {
type Protocols: BirthProtocolProduct;
}
pub trait SendsFor<Event>: SendEffects {}
pub trait SourceAction: ActionItem {
type Source;
}
pub struct SourceActions<Item> {
items: Vec<Item>,
}
impl<Item> SourceActions<Item> {
#[must_use]
pub fn len(&self) -> usize {
self.items.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
#[must_use]
pub fn into_items(self) -> Vec<Item> {
self.items
}
}
impl<Item> SendEffects for SourceActions<Item> {
fn empty() -> Self {
Self { items: Vec::new() }
}
fn append(&mut self, mut other: Self) {
self.items.append(&mut other.items);
}
}
impl<Item> SendInput<Item, Own> for SourceActions<Item> {
fn emit(&mut self, input: Item) {
self.items.push(input);
}
}
impl<Item> LogicalDeliveryProtocols for SourceActions<Item> {
type Protocols = crate::NoBirthProtocols;
}
impl<Event, Item> SendsFor<Event> for SourceActions<Item> where Item: SourceAction {}
pub struct SourceSettlements<Item>
where
Item: SourceAction,
{
inputs: Vec<ActionItemResult<Item>>,
}
impl<Item> SourceSettlements<Item>
where
Item: SourceAction,
{
fn new(inputs: Vec<ActionItemResult<Item>>) -> Self {
Self { inputs }
}
#[must_use]
pub fn into_inputs(self) -> Vec<ActionItemResult<Item>> {
self.inputs
}
}
impl<Item> ClassifySettlement for SourceSettlements<Item>
where
Item: SourceAction,
{
fn settlement_status(&self) -> SettlementStatus {
self.inputs.settlement_status()
}
}
impl<Item> SendSettlements for SourceActions<Item>
where
Item: SourceAction,
{
type Settlements = SourceSettlements<Item>;
fn unattempted(self) -> Self::Settlements {
SourceSettlements::new(
self.items
.into_iter()
.map(SettledItem::Unattempted)
.collect(),
)
}
}
impl<Interpreter, RootEvent, Path, Item> InterpretSends<Interpreter, RootEvent, Path>
for SourceActions<Item>
where
Interpreter: InterpretItem<Item, RootEvent, Path>,
Item: SourceAction,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
async move {
let mut items = self.items.into_iter();
let mut inputs = Vec::with_capacity(items.len());
while let Some(item) = items.next() {
match settle_item::<Item, Interpreter, RootEvent, Path>(item, interpreter).await {
Interpretation::Complete(settlement) => {
inputs.push(settlement);
}
Interpretation::Corrupt(settlement) => {
inputs.push(settlement);
inputs.extend(items.map(SettledItem::Unattempted));
return Interpretation::Corrupt(SourceSettlements::new(inputs));
}
}
}
Interpretation::Complete(SourceSettlements::new(inputs))
}
}
}
pub trait SourceAdmission<RootEvent, Source, Input>: Send
where
RootEvent: crate::EventIngress<Source, Input>,
{
fn admit_source(&mut self, input: Input) -> impl Future<Output = Result<(), Input>> + Send;
}
pub enum SourceCustody<Residual> {
Open(Residual),
Closed(Residual),
}
pub trait SourceSettlementCustody<Host, RootEvent>: Sized {
fn offer_to_source(self, host: &mut Host) -> impl Future<Output = SourceCustody<Self>> + Send;
}
impl<Host, RootEvent, Item> SourceSettlementCustody<Host, RootEvent> for SourceSettlements<Item>
where
Host: SourceAdmission<RootEvent, Item::Source, ActionItemResult<Item>>,
RootEvent: crate::EventIngress<Item::Source, ActionItemResult<Item>>,
Item: SourceAction,
{
fn offer_to_source(self, host: &mut Host) -> impl Future<Output = SourceCustody<Self>> + Send {
async move {
let mut source_inputs = self.inputs.into_iter();
let mut residual = Vec::new();
while let Some(input) = source_inputs.next() {
match host.admit_source(input).await {
Ok(()) => {}
Err(input) => {
residual.push(input);
residual.extend(source_inputs);
return SourceCustody::Closed(Self::new(residual));
}
}
}
SourceCustody::Open(Self::new(residual))
}
}
}
impl<Host, RootEvent> SourceSettlementCustody<Host, RootEvent> for NoSends {
fn offer_to_source(self, _: &mut Host) -> impl Future<Output = SourceCustody<Self>> + Send {
async move { SourceCustody::Open(self) }
}
}
impl<Host, RootEvent, Item> SourceSettlementCustody<Host, RootEvent> for Vec<ActionItemResult<Item>>
where
Item: ActionItem,
{
fn offer_to_source(self, _: &mut Host) -> impl Future<Output = SourceCustody<Self>> + Send {
async move { SourceCustody::Open(self) }
}
}
impl<Host, RootEvent> SourceSettlementCustody<Host, RootEvent> for Vec<crate::Never> {
fn offer_to_source(self, _: &mut Host) -> impl Future<Output = SourceCustody<Self>> + Send {
async move { SourceCustody::Open(self) }
}
}
impl<Host, RootEvent, Owned, Inner> SourceSettlementCustody<Host, RootEvent>
for SendLayer<Owned, Inner>
where
Host: Send,
Owned: SourceSettlementCustody<Host, RootEvent> + Send,
Inner: SourceSettlementCustody<Host, RootEvent> + Send,
{
fn offer_to_source(self, host: &mut Host) -> impl Future<Output = SourceCustody<Self>> + Send {
async move {
match self.inner.offer_to_source(host).await {
SourceCustody::Open(inner) => match self.owned.offer_to_source(host).await {
SourceCustody::Open(owned) => SourceCustody::Open(SendLayer::new(owned, inner)),
SourceCustody::Closed(owned) => {
SourceCustody::Closed(SendLayer::new(owned, inner))
}
},
SourceCustody::Closed(inner) => {
SourceCustody::Closed(SendLayer::new(self.owned, inner))
}
}
}
}
}
pub enum NoReturnToEmitter {}
pub struct ReturnsToEmitter<Input, Path>(core::marker::PhantomData<fn(Input, Path)>);
pub trait ReturnToEmitterFor<Event> {}
impl<Event> ReturnToEmitterFor<Event> for NoReturnToEmitter {}
impl<Event, Input, Path> ReturnToEmitterFor<Event> for ReturnsToEmitter<Input, Path> where
Event: InjectEvent<Input, Path>
{
}
pub trait InterpreterRequest {
type ReturnToEmitter;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ReportToParent<R> {
pub report: R,
}
impl<R> ReportToParent<R> {
#[must_use]
pub const fn new(report: R) -> Self {
Self { report }
}
#[must_use]
pub fn into_inner(self) -> R {
self.report
}
}
impl<R> InterpreterRequest for ReportToParent<R> {
type ReturnToEmitter = NoReturnToEmitter;
}
impl<R> ActionItem for ReportToParent<R>
where
R: Send,
{
type Accepted = ();
type Rejection = ParentReportReason;
type Prerequisite = crate::Never;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoSends;
impl SendEffects for NoSends {
fn empty() -> Self {
Self
}
fn append(&mut self, _: Self) {}
}
impl LogicalDeliveryProtocols for NoSends {
type Protocols = NoBirthProtocols;
}
impl<Event> SendsFor<Event> for NoSends {}
impl SendSettlements for NoSends {
type Settlements = Self;
fn unattempted(self) -> Self::Settlements {
self
}
}
impl ClassifySettlement for NoSends {
fn settlement_status(&self) -> SettlementStatus {
SettlementStatus::Accepted
}
}
impl<Interpreter, RootEvent, Path> InterpretSends<Interpreter, RootEvent, Path> for NoSends {
fn interpret(
self,
_: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
async move { Interpretation::Complete(self) }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SendLayer<Owned, Inner> {
pub owned: Owned,
pub inner: Inner,
}
impl<Owned, Inner> SendLayer<Owned, Inner> {
#[must_use]
pub const fn new(owned: Owned, inner: Inner) -> Self {
Self { owned, inner }
}
}
impl<Owned: SendEffects, Inner: SendEffects> SendEffects for SendLayer<Owned, Inner> {
fn empty() -> Self {
Self::new(Owned::empty(), Inner::empty())
}
fn append(&mut self, other: Self) {
self.owned.append(other.owned);
self.inner.append(other.inner);
}
}
impl<Owned, Inner> LogicalDeliveryProtocols for SendLayer<Owned, Inner>
where
Owned: LogicalDeliveryProtocols,
Inner: LogicalDeliveryProtocols,
{
type Protocols = <Inner::Protocols as BirthProtocolProduct>::Append<Owned::Protocols>;
}
impl<Event, OwnedEffects, InnerEffects> SendsFor<Event> for SendLayer<OwnedEffects, InnerEffects>
where
Event: ComposedEvent,
OwnedEffects: SendsFor<Event>,
InnerEffects: SendsFor<Event::Inner>,
{
}
impl<Owned, Inner> SendSettlements for SendLayer<Owned, Inner>
where
Owned: SendSettlements,
Inner: SendSettlements,
{
type Settlements = SendLayer<Owned::Settlements, Inner::Settlements>;
fn unattempted(self) -> Self::Settlements {
SendLayer::new(self.owned.unattempted(), self.inner.unattempted())
}
}
impl<Owned, Inner> ClassifySettlement for SendLayer<Owned, Inner>
where
Owned: ClassifySettlement,
Inner: ClassifySettlement,
{
fn settlement_status(&self) -> SettlementStatus {
self.inner
.settlement_status()
.combine(self.owned.settlement_status())
}
}
impl<Input, Path, Owned, Inner> SendInput<Input, Path> for SendLayer<Owned, Inner>
where
Owned: SendInput<Input, Path>,
{
fn emit(&mut self, input: Input) {
self.owned.emit(input);
}
}
impl<Interpreter, RootEvent, Path, Owned, Inner> InterpretSends<Interpreter, RootEvent, Path>
for SendLayer<Owned, Inner>
where
Interpreter: Send,
Owned: InterpretSends<Interpreter, RootEvent, Path> + Send,
Inner: InterpretSends<Interpreter, RootEvent, Inside<Path>> + Send,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
async move {
let inner = <Inner as InterpretSends<Interpreter, RootEvent, Inside<Path>>>::interpret(
self.inner,
interpreter,
)
.await;
let inner = match inner {
Interpretation::Complete(inner) => inner,
Interpretation::Corrupt(inner) => {
return Interpretation::Corrupt(SendLayer::new(
self.owned.unattempted(),
inner,
));
}
};
match <Owned as InterpretSends<Interpreter, RootEvent, Path>>::interpret(
self.owned,
interpreter,
)
.await
{
Interpretation::Complete(owned) => {
Interpretation::Complete(SendLayer::new(owned, inner))
}
Interpretation::Corrupt(owned) => {
Interpretation::Corrupt(SendLayer::new(owned, inner))
}
}
}
}
}
impl<T> SendEffects for Vec<T> {
fn empty() -> Self {
Vec::new()
}
fn append(&mut self, mut other: Self) {
Vec::append(self, &mut other);
}
}
impl<P: Protocol> LogicalDeliveryProtocols for Vec<Delivery<P>> {
type Protocols = BirthProtocol<P, NoBirthProtocols>;
}
impl<P: Protocol, Occurrence> LogicalDeliveryProtocols for Vec<ChildDelivery<P, Occurrence>> {
type Protocols = NoBirthProtocols;
}
impl<Child, Source, Input, Occurrence> LogicalDeliveryProtocols
for Vec<ChildInput<Child, Source, Input, Occurrence>>
where
Child: Behavior,
{
type Protocols = NoBirthProtocols;
}
impl<P> LogicalDeliveryProtocols for Vec<EstablishedDelivery<P>>
where
P: Protocol,
P::Addr: EndpointAddress,
{
type Protocols = NoBirthProtocols;
}
impl LogicalDeliveryProtocols for Vec<crate::Never> {
type Protocols = NoBirthProtocols;
}
impl<Event, T> SendsFor<Event> for Vec<T> {}
impl<Item> SendSettlements for Vec<Item>
where
Item: ActionItem,
{
type Settlements = Vec<ActionItemResult<Item>>;
fn unattempted(self) -> Self::Settlements {
unattempted_items(self)
}
}
pub async fn settle_item<Item, Interpreter, RootEvent, Path>(
item: Item,
interpreter: &mut Interpreter,
) -> Interpretation<ActionItemResult<Item>>
where
Item: ActionItem,
Interpreter: InterpretItem<Item, RootEvent, Path>,
{
let settlement =
<Interpreter as InterpretItem<Item, RootEvent, Path>>::interpret_item(interpreter, item)
.await;
match settlement {
corrupt @ ItemSettlement::Corrupt { .. } => {
Interpretation::Corrupt(SettledItem::Attempted(corrupt))
}
settled => Interpretation::Complete(SettledItem::Attempted(settled)),
}
}
async fn interpret_items<Item, Interpreter, RootEvent, Path>(
items: Vec<Item>,
interpreter: &mut Interpreter,
) -> Interpretation<Vec<ActionItemResult<Item>>>
where
Item: ActionItem,
Interpreter: InterpretItem<Item, RootEvent, Path>,
{
let mut items = items.into_iter();
let mut settlements = Vec::with_capacity(items.len());
while let Some(item) = items.next() {
match settle_item::<Item, Interpreter, RootEvent, Path>(item, interpreter).await {
Interpretation::Complete(settlement) => settlements.push(settlement),
Interpretation::Corrupt(settlement) => {
settlements.push(settlement);
settlements.extend(items.map(SettledItem::Unattempted));
return Interpretation::Corrupt(settlements);
}
}
}
Interpretation::Complete(settlements)
}
fn unattempted_items<Item>(items: Vec<Item>) -> Vec<ActionItemResult<Item>>
where
Item: ActionItem,
{
items.into_iter().map(SettledItem::Unattempted).collect()
}
impl<Interpreter, RootEvent, Path, P> InterpretSends<Interpreter, RootEvent, Path>
for Vec<Delivery<P>>
where
Interpreter: InterpretItem<Delivery<P>, RootEvent, Path>,
P: Protocol,
Delivery<P>: ActionItem,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
interpret_items(self, interpreter)
}
}
impl<Interpreter, RootEvent, Path, P, Occurrence> InterpretSends<Interpreter, RootEvent, Path>
for Vec<ChildDelivery<P, Occurrence>>
where
Interpreter: InterpretItem<ChildDelivery<P, Occurrence>, RootEvent, Path>,
P: Protocol,
ChildDelivery<P, Occurrence>: ActionItem,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
interpret_items(self, interpreter)
}
}
impl<Interpreter, RootEvent, Path, Child, Source, Input, Occurrence>
InterpretSends<Interpreter, RootEvent, Path>
for Vec<ChildInput<Child, Source, Input, Occurrence>>
where
Interpreter: InterpretItem<ChildInput<Child, Source, Input, Occurrence>, RootEvent, Path>,
Child: Behavior,
Child::Event: crate::ChildInputIngress<Source, Input>,
ChildInput<Child, Source, Input, Occurrence>: ActionItem,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
interpret_items(self, interpreter)
}
}
impl<Interpreter, RootEvent, Path, P> InterpretSends<Interpreter, RootEvent, Path>
for Vec<EstablishedDelivery<P>>
where
Interpreter: InterpretItem<EstablishedDelivery<P>, RootEvent, Path>,
P: Protocol,
P::Addr: EndpointAddress,
EstablishedDelivery<P>: ActionItem,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
interpret_items(self, interpreter)
}
}
impl SendSettlements for Vec<crate::Never> {
type Settlements = Self;
fn unattempted(self) -> Self::Settlements {
self
}
}
impl<Interpreter, RootEvent, Path> InterpretSends<Interpreter, RootEvent, Path>
for Vec<crate::Never>
{
fn interpret(
self,
_: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
async move { Interpretation::Complete(self) }
}
}
impl<T> SendInput<T, Own> for Vec<T> {
fn emit(&mut self, input: T) {
self.push(input);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterpreterRequests<M> {
requests: Vec<M>,
}
impl<M> InterpreterRequests<M> {
#[must_use]
pub fn new(requests: Vec<M>) -> Self {
Self { requests }
}
#[must_use]
pub fn one(request: M) -> Self {
Self::new(vec![request])
}
#[must_use]
pub fn as_slice(&self) -> &[M] {
&self.requests
}
pub fn iter(&self) -> core::slice::Iter<'_, M> {
self.requests.iter()
}
#[must_use]
pub fn len(&self) -> usize {
self.requests.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.requests.is_empty()
}
pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
self.requests.extend(requests);
}
#[must_use]
pub fn into_requests(self) -> Vec<M> {
self.requests
}
}
impl<M> core::ops::Index<usize> for InterpreterRequests<M> {
type Output = M;
fn index(&self, index: usize) -> &Self::Output {
&self.requests[index]
}
}
impl<M> IntoIterator for InterpreterRequests<M> {
type Item = M;
type IntoIter = std::vec::IntoIter<M>;
fn into_iter(self) -> Self::IntoIter {
self.requests.into_iter()
}
}
impl<'a, M> IntoIterator for &'a InterpreterRequests<M> {
type Item = &'a M;
type IntoIter = core::slice::Iter<'a, M>;
fn into_iter(self) -> Self::IntoIter {
self.requests.iter()
}
}
impl<M> SendEffects for InterpreterRequests<M> {
fn empty() -> Self {
Self::new(Vec::new())
}
fn append(&mut self, mut other: Self) {
self.requests.append(&mut other.requests);
}
}
impl<M> LogicalDeliveryProtocols for InterpreterRequests<M> {
type Protocols = NoBirthProtocols;
}
impl<Event, M> SendsFor<Event> for InterpreterRequests<M>
where
M: InterpreterRequest,
M::ReturnToEmitter: ReturnToEmitterFor<Event>,
{
}
impl<M> SendInput<M, Own> for InterpreterRequests<M> {
fn emit(&mut self, input: M) {
self.requests.push(input);
}
}
impl<Request> SendSettlements for InterpreterRequests<Request>
where
Request: ActionItem,
{
type Settlements = Vec<ActionItemResult<Request>>;
fn unattempted(self) -> Self::Settlements {
unattempted_items(self.requests)
}
}
impl<Interpreter, RootEvent, Path, Request> InterpretSends<Interpreter, RootEvent, Path>
for InterpreterRequests<Request>
where
Interpreter: InterpretItem<Request, RootEvent, Path>,
Request: ActionItem,
{
fn interpret(
self,
interpreter: &mut Interpreter,
) -> impl Future<Output = Interpretation<Self::Settlements>> + Send {
interpret_items(self.requests, interpreter)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn send_accumulation_obeys_identity_and_associativity() {
let values = vec![1, 2];
assert_eq!(Vec::new().combine(values.clone()), values);
assert_eq!(values.clone().combine(Vec::new()), values);
let left = vec![1].combine(vec![2]).combine(vec![3]);
let right = vec![1].combine(vec![2].combine(vec![3]));
assert_eq!(left, right);
}
#[test]
fn vector_and_service_lanes_emit_and_iterate_in_order() {
assert!(<Vec<u8> as SendEffects>::empty().is_empty());
let mut vector = Vec::new();
<Vec<u8> as SendInput<u8, Own>>::emit(&mut vector, 1);
assert_eq!(vector, [1]);
let mut services = InterpreterRequests::one(2);
services.extend([4, 5]);
<InterpreterRequests<u8> as SendInput<u8, Own>>::emit(&mut services, 3);
assert!(!services.is_empty());
assert_eq!(services.as_slice(), [2, 4, 5, 3]);
assert_eq!(
(&services).into_iter().copied().collect::<Vec<_>>(),
[2, 4, 5, 3]
);
assert_eq!(services.into_iter().collect::<Vec<_>>(), [2, 4, 5, 3]);
let requests = InterpreterRequests::new(vec![4, 5]).into_requests();
assert_eq!(requests, [4, 5]);
}
#[test]
fn source_and_interpreter_lanes_report_complete_ordered_contents() {
let empty = <SourceActions<u8> as SendEffects>::empty();
assert!(empty.is_empty());
assert_eq!(empty.len(), 0);
let mut prefix = <SourceActions<u8> as SendEffects>::empty();
<SourceActions<u8> as SendInput<u8, Own>>::emit(&mut prefix, 1);
<SourceActions<u8> as SendInput<u8, Own>>::emit(&mut prefix, 2);
let mut suffix = <SourceActions<u8> as SendEffects>::empty();
<SourceActions<u8> as SendInput<u8, Own>>::emit(&mut suffix, 3);
<SourceActions<u8> as SendInput<u8, Own>>::emit(&mut suffix, 4);
prefix.append(suffix);
assert!(!prefix.is_empty());
assert_eq!(prefix.len(), 4);
assert_eq!(prefix.into_items(), [1, 2, 3, 4]);
let requests = InterpreterRequests::new(vec![5, 6, 7]);
assert_eq!(requests.len(), 3);
}
struct Returning;
impl InterpreterRequest for Returning {
type ReturnToEmitter = ReturnsToEmitter<u8, crate::Here>;
}
fn lawful<Event, Effects: SendsFor<Event>>() {}
#[test]
fn local_return_proofs_compose_through_exact_event_layers() {
type Inner = crate::EventLayer<u8, crate::User<crate::MailAddr, ()>>;
type Outer = crate::EventLayer<(), Inner>;
lawful::<Inner, InterpreterRequests<Returning>>();
lawful::<Outer, SendLayer<NoSends, InterpreterRequests<Returning>>>();
}
#[test]
fn send_layer_emits_into_its_designated_owned_lane() {
let mut effects = SendLayer::new(Vec::<u8>::new(), Vec::<u16>::new());
<SendLayer<Vec<u8>, Vec<u16>> as SendInput<u8, Own>>::emit(&mut effects, 7);
assert_eq!(effects.owned, [7]);
assert!(effects.inner.is_empty());
}
#[derive(Debug, PartialEq, Eq)]
enum Seen {
Inner(u8),
Outer(u16),
}
struct Trace(Vec<Seen>);
type TraceEvent =
crate::EventLayer<u16, crate::EventLayer<u8, crate::User<crate::MailAddr, ()>>>;
impl ActionItem for u8 {
type Accepted = ();
type Rejection = crate::Never;
type Prerequisite = crate::Never;
}
impl ActionItem for u16 {
type Accepted = ();
type Rejection = crate::Never;
type Prerequisite = crate::Never;
}
impl InterpretItem<u8, TraceEvent, crate::Inside<crate::Here>> for Trace {
fn interpret_item(
&mut self,
request: u8,
) -> impl Future<
Output = ItemSettlement<
u8,
<u8 as ActionItem>::Accepted,
<u8 as ActionItem>::Rejection,
<u8 as ActionItem>::Prerequisite,
>,
> + Send {
async move {
self.0.push(Seen::Inner(request));
ItemSettlement::Accepted(())
}
}
}
impl InterpretItem<u16, TraceEvent, crate::Here> for Trace {
fn interpret_item(
&mut self,
request: u16,
) -> impl Future<
Output = ItemSettlement<
u16,
<u16 as ActionItem>::Accepted,
<u16 as ActionItem>::Rejection,
<u16 as ActionItem>::Prerequisite,
>,
> + Send {
async move {
self.0.push(Seen::Outer(request));
ItemSettlement::Accepted(())
}
}
}
#[tokio::test]
async fn structural_interpretation_visits_every_lane_inner_to_outer() {
let effects = SendLayer::new(
InterpreterRequests::new(vec![3_u16, 5]),
SendLayer::new(InterpreterRequests::one(2_u8), NoSends),
);
let mut trace = Trace(Vec::new());
<_ as InterpretSends<_, TraceEvent, crate::Here>>::interpret(effects, &mut trace).await;
assert_eq!(trace.0, [Seen::Inner(2), Seen::Outer(3), Seen::Outer(5)]);
}
}