dope-manifold 0.22.0

Owned application and service composition for dope
Documentation
use std::{ops::ControlFlow, pin};

use dope_core::driver::{retained, route::Identity, schedule};
use dope_net::{
    link::{
        event,
        pool::recv::{arrival, delivery, input, reserve::Choice},
    },
    wire,
    wire::receive::{Chunk, mode::Disabled},
};

use crate::app::receive::ingress::{
    self, Admission as _, Dispatch, Replay, Strategy, dispatch::flow,
};

pub(crate) struct Scope;

impl<W, M> Strategy<W, M> for Scope
where
    W: wire::Spec,
    M: Dispatch<W, Strategy = Scope>,
    M::Kind: delivery::ScopedData + input::Replay<W>,
{
    type Value<'input, 'w, 'd>
        = Chunk<'w, 'd, W, Disabled>
    where
        'd: 'w,
        'w: 'input,
        W: 'w + 'd;

    type Pending<'w, 'd>
        = Chunk<'w, 'd, W, Disabled>
    where
        'd: 'w,
        W: 'w + 'd;

    type Admission<'a, 'c, 'owner, 'd>
        = ingress::Single<'a, 'c, 'owner, 'd>
    where
        'c: 'a,
        'owner: 'a,
        'd: 'a + 'c + 'owner,
        W: 'd;

    fn drive_data<'p, 'a, 'c, 'owner, 'w, 'd, ID: Identity + 'd, P, A>(
        policy: pin::Pin<&mut P>,
        data: A,
        work: Self::Admission<'a, 'c, 'owner, 'd>,
    ) where
        'c: 'a,
        'owner: 'a,
        'd: 'a + 'c + 'owner + 'w + 'p,
        W: 'w + 'd,
        P: ingress::Policy<'p, 'w, 'd, ID, Wire = W, Input = M>,
        M::Reserve: Choice<W, M::Ingress>,
        A: arrival::Arrival<'d, Observed = event::Data<'d>>,
    {
        work.drive(
            policy,
            data,
            |prep| prep.scoped(),
            |policy, next, turn, driver| {
                flow::apply(
                    policy,
                    next,
                    turn,
                    driver,
                    |policy, key, input, turn, driver| {
                        P::receive(policy, key, M::from_value(input), turn, driver)
                    },
                )
            },
        )
    }

    fn resume_tail<'p, 'w, 'd, ID: Identity + 'd, P>(
        mut policy: pin::Pin<&mut P>,
        item: &delivery::Resumed<'d, ID>,
        first: bool,
        turn: schedule::Turn<'_, 'd>,
        driver: &mut retained::Context<'_, '_, 'd>,
    ) -> ControlFlow<(), bool>
    where
        'd: 'w + 'p,
        W: 'w + 'd,
        P: ingress::Policy<'p, 'w, 'd, ID, Wire = W, Input = M>,
        M::Reserve: Choice<W, M::Ingress>,
    {
        let (key, chunk, work) = {
            let mut recv = P::storage(policy.as_mut()).recv();
            let Some((key, taken)) = recv.take_tail(item)? else {
                return ControlFlow::Continue(false);
            };
            let replay = if first {
                Replay::First
            } else {
                Replay::Waiting
            };
            let work = match <Self as Strategy<W, M>>::Admission::replay(
                replay,
                item.ready(),
                turn.reborrow(),
                driver,
            ) {
                schedule::Capacity::Available(work) => work,
                schedule::Capacity::Exhausted => return ControlFlow::Break(()),
            };
            (key, taken.commit(), work)
        };
        let (driver, step) = work.into();
        ingress::prepare_terminal(policy.as_mut(), key);
        let done = P::receive(
            policy.as_mut(),
            key,
            M::from_value(chunk),
            step.reborrow(),
            driver,
        );
        flow::settle(policy.as_mut(), key, done, step.reborrow(), driver)?;
        P::storage(policy).recv().finish_tail(item);
        ControlFlow::Continue(true)
    }
}