use core::{num::NonZero, ops::ControlFlow};
use o3::buffer::segments;
use sark_http::field;
use crate::{life::session, manifold};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[repr(u8)]
pub enum Boundary {
#[default]
More,
End,
}
const _: () = {
assert!(core::mem::size_of::<Boundary>() == core::mem::size_of::<bool>());
assert!(core::mem::align_of::<Boundary>() == core::mem::align_of::<bool>());
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum Section {
Initial,
Trailing,
}
const _: () = {
assert!(core::mem::size_of::<Section>() == core::mem::size_of::<bool>());
assert!(core::mem::align_of::<Section>() == core::mem::align_of::<bool>());
};
pub trait Message: Copy {
type Key: manifold::raw::Key;
fn key(self) -> Self::Key;
fn boundary(self) -> Boundary;
}
pub trait Payload<C: session::Storage>: Sized {
type Permit;
fn into_parts(self) -> (segments::Chain<C>, Self::Permit);
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Control<B> {
Written,
Prepared(B),
Blocked(B),
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Data<B> {
Written(NonZero<usize>),
Blocked(B),
}
pub trait Write<P> {
type Block;
type Error;
fn headers<S: field::Source>(
&mut self,
source: S,
boundary: Boundary,
) -> Result<Control<Self::Block>, Self::Error>;
fn data(
&mut self,
prefix: &[u8],
payload: &P,
offset: usize,
boundary: Boundary,
) -> Result<Data<Self::Block>, Self::Error>;
fn commit(&mut self) -> Result<ControlFlow<Self::Block>, Self::Error>;
fn discard(&mut self);
}