dope-core 0.22.0

Owned native I/O and completion driver for dope
Documentation
use std::marker;

use dope_sys::table::token::host;

use crate::{
    driver::{
        self,
        retained::flight::{GENERATION_BITS, INDEX_BITS, Mismatch, Target, storage},
        route::{self, kind},
    },
    io::event::batch::Flow,
};

#[must_use = "a validated flight completion must be committed"]
pub(crate) struct Complete<'q, 'd, C: kind::Class = kind::Any> {
    pub(super) completion: storage::Complete<'q, Target, INDEX_BITS, GENERATION_BITS>,
    pub(super) driver: driver::Reference<'d>,
    pub(super) class: marker::PhantomData<C>,
}

impl<'q, 'd> Complete<'q, 'd> {
    pub(crate) fn bind<C: kind::Flight>(self, proof: kind::Witness<C>) -> Complete<'q, 'd, C> {
        Complete {
            completion: self.completion,
            driver: self.driver,
            class: proof.marker(),
        }
    }

    pub(crate) fn kind(&self) -> kind::Native {
        self.completion.value().kind
    }
}

impl<'q, 'd, C: kind::Flight> TryFrom<Complete<'q, 'd>> for Complete<'q, 'd, C> {
    type Error = Mismatch<'q, 'd>;

    fn try_from(bound: Complete<'q, 'd>) -> Result<Self, Self::Error> {
        let observed = bound.kind();
        let Some(proof) = observed.witness() else {
            return Err(Mismatch {
                bound,
                expected: C::FLIGHT,
                observed,
            });
        };
        Ok(bound.bind(proof))
    }
}

impl<'d, C: kind::Class> From<&Complete<'_, 'd, C>> for route::Erased<'d, C> {
    fn from(bound: &Complete<'_, 'd, C>) -> Self {
        bound.completion.value().bind(
            bound.driver.brand,
            super::raw::Echo::from_inner(bound.completion.echo()),
        )
    }
}

impl<'d, C: kind::Class> Complete<'_, 'd, C> {
    pub(crate) const fn driver(&self) -> driver::Reference<'d> {
        self.driver
    }

    pub(crate) fn complete(self) -> route::Erased<'d, C> {
        let echo = super::raw::Echo::from_inner(self.completion.echo());
        self.completion.complete().bind(self.driver.brand, echo)
    }

    pub(crate) fn settle(self, flow: Flow) -> route::Erased<'d, C> {
        let echo = super::raw::Echo::from_inner(self.completion.echo());
        self.completion.settle(flow).bind(self.driver.brand, echo)
    }
}

impl<C: kind::Class> host::Flight<Flow> for Complete<'_, '_, C> {
    type Key = super::raw::Echo;

    fn finish(self) {
        self.completion.finish();
    }

    fn end(self, flow: Flow) -> Self::Key {
        let echo = super::raw::Echo::from_inner(self.completion.echo());
        if flow == Flow::Last {
            self.completion.finish();
        }
        echo
    }
}