use std::convert::Infallible;
use dope_core::{
driver::{
self, result, retained,
retained::flight,
route::{self, kind},
},
io::fd::handles,
};
use crate::wire::send::{
self, Either, Submitted,
sources::{plain::Slice, vectored::Vectors},
};
pub trait Plain<'a> {
unsafe fn retain(self) -> send::Plain<'a>;
}
impl<'a> Plain<'a> for &'a [u8] {
unsafe fn retain(self) -> send::Plain<'a> {
send::Plain::proven(self)
}
}
pub trait Ready<'a> {
unsafe fn submit<'d: 'a, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: driver::Context<'_, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>;
}
impl<'a> Ready<'a> for Infallible {
unsafe fn submit<'d: 'a, Tag: route::Tag + route::Select<kind::Send>>(
self,
_: &handles::Descriptor<'d>,
_: route::Target<'d, Tag>,
_: &flight::Slots<'d, Tag>,
_: driver::Context<'_, 'd>,
) -> Result<Submitted<'d>, result::SubmitError> {
match self {}
}
}
impl<'a> Ready<'a> for Slice<'a> {
unsafe fn submit<'d: 'a, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: driver::Context<'_, 'd>,
) -> Result<Submitted<'d>, result::SubmitError> {
let op = retained::raw::Submission::send(fd, self.view, target);
let flight = unsafe { op.try_submit(driver, slots) }?;
Ok(Submitted {
bytes: self.bytes,
flight,
})
}
}
impl<'a> Ready<'a> for Vectors<'a> {
unsafe fn submit<'d: 'a, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: driver::Context<'_, 'd>,
) -> Result<Submitted<'d>, result::SubmitError> {
let op = retained::raw::Submission::send_msg(fd, self.message, target);
let flight = unsafe { op.try_submit(driver, slots) }?;
Ok(Submitted {
bytes: self.bytes,
flight,
})
}
}
impl<'a, L: Ready<'a>, R: Ready<'a>> Ready<'a> for Either<L, R> {
unsafe fn submit<'d: 'a, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: driver::Context<'_, 'd>,
) -> Result<Submitted<'d>, result::SubmitError> {
match self {
Self::Left(data) => unsafe { data.submit(fd, target, slots, driver) },
Self::Right(data) => unsafe { data.submit(fd, target, slots, driver) },
}
}
}
pub(crate) fn submit<'a, 'd: 'a, Tag: route::Tag + route::Select<kind::Send>>(
ready: impl Ready<'a>,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: driver::Context<'_, 'd>,
) -> Result<Submitted<'d>, result::SubmitError> {
unsafe { ready.submit(fd, target, slots, driver) }
}