dope-core 0.23.0

Owned native I/O and completion driver for dope
Documentation
use dope_sys::{
    io::socket::option::tuning,
    probe::Stopped,
    table::token::{self, host::Flight as _},
};

use crate::{
    Errno,
    driver::{
        life::native,
        result::poll::fault,
        retained::flight,
        route::{indices, kind, kind::Shape},
    },
    io,
    io::{
        event::{Kind, batch::Flow, net::connect},
        outputs,
        socket::option,
    },
};

pub(crate) struct Tuned<'q, 'd, S> {
    state: S,
    flight: Terminal<'q, 'd>,
}

enum Terminal<'q, 'd> {
    Connect(flight::Complete<'q, 'd, kind::Connect>),
    Tuning(flight::Complete<'q, 'd, kind::Tuning>),
}

pub(crate) enum Failure<'q, 'd, S> {
    Lookup(tuning::Missing),
    Stale(Stopped<S, flight::raw::Echo>),
    Class(Stopped<(S, flight::Complete<'q, 'd>), kind::Native>),
}

impl<'q, 'd, S: tuning::Occupied<flight::raw::Echo>> Tuned<'q, 'd, S> {
    pub(super) fn complete(self, outcome: Result<(), Errno>) -> io::Event<'d> {
        let Self { state, flight } = self;
        let option_failed = state.option_failed();
        state.clear();
        match flight {
            Terminal::Connect(bound) => outputs::connected(
                bound.complete(),
                outcome.map_err(|errno| classify(errno, option_failed)),
            ),
            Terminal::Tuning(bound) => Kind::Tuning((bound, outcome).into()).into(),
        }
    }

    pub(super) fn reclaim(self, result: Result<(), Errno>) -> native::Report {
        let Self { state, flight } = self;
        let option_failed = state.option_failed();
        state.clear();
        native::Report(match flight {
            Terminal::Connect(bound) => io::Reclaimed::Connect {
                echo: fault::Echo::new(bound.end(Flow::Last)),
                result: result.map_err(|errno| classify(errno, option_failed)),
            },
            Terminal::Tuning(bound) => io::Reclaimed::Tuning {
                echo: fault::Echo::new(bound.end(Flow::Last)),
                result,
            },
        })
    }
    pub(super) fn bind<'state, T, C>(
        states: &'state mut T,
        drain: &'q flight::Drain<'q, 'd>,
        txn: C,
    ) -> Result<Self, Failure<'q, 'd, S>>
    where
        T: tuning::Table<flight::raw::Echo, { option::MAX_STREAM_OPTIONS }, Occupied<'state> = S>
            + 'state,
        C: token::Tuning<Slot = indices::SlotIndex>,
    {
        let state = states.bind(txn.slot().raw()).map_err(Failure::Lookup)?;
        let target = state.target();
        use dope_sys::table::token::host::Drain as _;
        let (state, flight) =
            Stopped::attach(state, drain.bind(target).ok_or(target)).map_err(Failure::Stale)?;
        let observed = flight.kind();
        let flight = match observed.into() {
            Shape::Connect(proof) => Terminal::Connect(flight.bind(proof)),
            Shape::Tuning(proof) => Terminal::Tuning(flight.bind(proof)),
            _ => {
                return Err(Failure::Class(Stopped {
                    state: (state, flight),
                    cause: observed,
                }));
            }
        };
        Ok(Tuned { state, flight })
    }
}

fn classify(errno: Errno, option_failed: bool) -> connect::Error {
    if option_failed {
        connect::Error::Option(errno)
    } else {
        connect::Error::Connect(errno)
    }
}