use std::convert::Infallible;
use dope_core::{
driver::{
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<'owner, 'd: 'owner, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: retained::Context<'_, 'owner, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>
where
'owner: 'a;
}
impl<'a> Ready<'a> for Infallible {
unsafe fn submit<'owner, 'd: 'owner, Tag: route::Tag + route::Select<kind::Send>>(
self,
_: &handles::Descriptor<'d>,
_: route::Target<'d, Tag>,
_: &flight::Slots<'d, Tag>,
_: retained::Context<'_, 'owner, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>
where
'owner: 'a,
{
match self {}
}
}
impl<'a> Ready<'a> for Slice<'a> {
unsafe fn submit<'owner, 'd: 'owner, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: retained::Context<'_, 'owner, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>
where
'owner: 'a,
{
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<'owner, 'd: 'owner, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: retained::Context<'_, 'owner, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>
where
'owner: 'a,
{
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<'owner, 'd: 'owner, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: retained::Context<'_, 'owner, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>
where
'owner: 'a,
{
match self {
Self::Left(data) => unsafe { data.submit(fd, target, slots, driver) },
Self::Right(data) => unsafe { data.submit(fd, target, slots, driver) },
}
}
}
pub(crate) struct Submission<R>(pub(crate) R);
impl<R> Submission<R> {
pub(crate) fn submit<'a, 'owner: 'a, 'd: 'owner, Tag: route::Tag + route::Select<kind::Send>>(
self,
fd: &handles::Descriptor<'d>,
target: route::Target<'d, Tag>,
slots: &flight::Slots<'d, Tag>,
driver: retained::Context<'_, 'owner, 'd>,
) -> Result<Submitted<'d>, result::SubmitError>
where
R: Ready<'a>,
{
unsafe { self.0.submit(fd, target, slots, driver) }
}
}