use crate::{
collections::Vector,
futures::{FnFut, FnFutWrapper},
http::{
AutoStream, Headers, MsgBufferString, Request, StatusCode,
http2_server_framework::{Endpoint, ResFinalizer, RouteMatch},
},
};
pub type State<'any, D> = StateGeneric<'any, D, false>;
pub type StateClean<'any, D> = StateGeneric<'any, D, true>;
#[derive(Debug)]
pub struct StateGeneric<'any, D, const CLEAN: bool> {
pub data: &'any mut D,
pub req: &'any mut Request<MsgBufferString>,
}
impl<'any, D, const CLEAN: bool> StateGeneric<'any, D, CLEAN> {
#[inline]
pub fn new(data: &'any mut D, req: &'any mut Request<MsgBufferString>) -> Self {
if CLEAN {
req.clear();
}
Self { data, req }
}
}
impl<D, E, F, RES, S, const CLEAN: bool> Endpoint<D, E, S>
for FnFutWrapper<(StateGeneric<'_, D, CLEAN>,), F>
where
E: From<crate::Error>,
F: for<'any> FnFut<(StateGeneric<'any, D, CLEAN>,), Result = RES>,
RES: ResFinalizer<E>,
{
#[inline]
async fn auto(
&self,
auto_stream: &mut AutoStream<D>,
_: (u8, &[RouteMatch]),
) -> Result<StatusCode, E> {
self
.0
.call((StateGeneric::new(&mut auto_stream.data, &mut auto_stream.req),))
.await
.finalize_response(&mut auto_stream.req)
}
}
impl<'any, D> From<State<'any, D>> for StateClean<'any, D> {
#[inline]
fn from(state: State<'any, D>) -> Self {
Self::new(state.data, state.req)
}
}
impl<'any, D, const CLEAN: bool> From<&'any mut (D, Request<MsgBufferString>)>
for StateGeneric<'any, D, CLEAN>
{
#[inline]
fn from((data, req): &'any mut (D, Request<MsgBufferString>)) -> Self {
Self::new(data, req)
}
}
impl<'any, D, const CLEAN: bool> From<&'any mut (&'any mut D, Request<MsgBufferString>)>
for StateGeneric<'any, D, CLEAN>
{
#[inline]
fn from((data, req): &'any mut (&'any mut D, Request<MsgBufferString>)) -> Self {
Self::new(data, req)
}
}
#[derive(Debug)]
pub struct StateTest<D> {
pub data: D,
pub req: Request<MsgBufferString>,
}
impl<D> StateTest<D> {
#[inline]
pub const fn parts_mut(&mut self) -> (&mut D, &mut Request<MsgBufferString>) {
(&mut self.data, &mut self.req)
}
#[inline]
pub const fn state<const CLEAR: bool>(&mut self) -> StateGeneric<'_, D, CLEAR> {
StateGeneric { data: &mut self.data, req: &mut self.req }
}
}
impl<D> StateTest<D> {
#[inline]
pub const fn parts_mut_with_body_and_headers(
&mut self,
) -> (&mut D, Request<(&mut Vector<u8>, &mut Headers)>) {
(
&mut self.data,
Request {
method: self.req.method,
msg_data: (&mut self.req.msg_data.body, &mut self.req.msg_data.headers),
},
)
}
}