use crate::{
Errno,
io::socket::option::tuning::device::{Admission, Failure, Finish, Options, Reserve},
};
pub unsafe trait Host<B, const N: usize>: Sized {
type File;
type Slot: Copy;
type Index: Copy;
type Reserve: Reserve;
type Options<'o>: Options<N>;
type Permit;
type Output;
type Error;
fn direct(
self,
run: impl for<'o> FnOnce(
&mut B,
Self::File,
Self::Slot,
Option<Self::Options<'o>>,
) -> Result<Self::File, (Self::File, Errno)>,
) -> Result<Self::Output, Self::Error>;
fn with(
self,
run: impl for<'o> FnOnce(
&mut B,
Self::File,
Self::Slot,
Self::Index,
Option<Self::Options<'o>>,
Self::Reserve,
) -> Result<
Finish<Self::File, <Self::Reserve as Reserve>::Reservation, Self::Permit>,
Failure<Self::File, <Self::Reserve as Reserve>::Error>,
>,
) -> Result<Self::Output, Self::Error>;
fn apply(
self,
run: impl for<'o> FnOnce(
Admission<'_, B, Self::File, Self::Slot, Self::Index>,
Option<Self::Options<'o>>,
Self::Reserve,
) -> Result<
Finish<Self::File, <Self::Reserve as Reserve>::Reservation, Self::Permit>,
Failure<Self::File, <Self::Reserve as Reserve>::Error>,
>,
) -> Result<Self::Output, Self::Error> {
self.with(|backend, file, slot, index, options, reserve| {
run(
Admission {
backend,
file,
slot,
index,
},
options,
reserve,
)
})
}
}
pub unsafe trait Connect<B, R, const N: usize>: Sized {
type File;
type Slot: Copy;
type Index: Copy;
type Reserve: Reserve;
type Options<'o>: Options<N>;
type Output;
type Error;
fn slot(file: &Self::File) -> Self::Slot;
fn target(file: &Self::File) -> (Self::Slot, Self::Index);
fn with(
self,
run: impl for<'o> FnOnce(
&mut B,
Self::File,
Option<Self::Options<'o>>,
Self::Reserve,
R,
) -> Result<
(Self::File, <Self::Reserve as Reserve>::Reservation),
Failure<Self::File, <Self::Reserve as Reserve>::Error>,
>,
) -> Result<Self::Output, Self::Error>;
fn direct(
self,
run: impl for<'o> FnOnce(
&mut B,
Self::File,
Option<(Self::Slot, Self::Options<'o>)>,
Self::Reserve,
R,
) -> Result<
(Self::File, <Self::Reserve as Reserve>::Reservation),
Failure<Self::File, <Self::Reserve as Reserve>::Error>,
>,
) -> Result<Self::Output, Self::Error> {
self.with(|backend, file, options, reserve, last| {
let options = options.map(|options| (Self::slot(&file), options));
run(backend, file, options, reserve, last)
})
}
fn connect(
self,
plain: impl FnOnce(
&mut B,
Self::File,
Self::Reserve,
R,
) -> Result<
(Self::File, <Self::Reserve as Reserve>::Reservation),
Failure<Self::File, <Self::Reserve as Reserve>::Error>,
>,
tuned: impl for<'o> FnOnce(
Admission<'_, B, Self::File, Self::Slot, Self::Index>,
Self::Options<'o>,
Self::Reserve,
R,
) -> Result<
(Self::File, <Self::Reserve as Reserve>::Reservation),
Failure<Self::File, <Self::Reserve as Reserve>::Error>,
>,
) -> Result<Self::Output, Self::Error> {
self.with(|backend, file, options, reserve, last| {
let Some(options) = options else {
return plain(backend, file, reserve, last);
};
let (slot, index) = Self::target(&file);
tuned(
Admission {
backend,
file,
slot,
index,
},
options,
reserve,
last,
)
})
}
}