use crate::{
collection::{Clear, Vector},
http::{Headers, Method, MsgData, MsgDataMut, Request, Response, StatusCode},
misc::{Lease, LeaseMut, Uri, UriRef},
};
use alloc::string::String;
use core::fmt::{Debug, Formatter};
pub type MsgBufferStr<'uri> = MsgBuffer<&'uri str>;
pub type MsgBufferString = MsgBuffer<String>;
pub struct MsgBuffer<S> {
pub body: Vector<u8>,
pub headers: Headers,
pub uri: Uri<S>,
}
impl<S> MsgBuffer<S> {
#[inline]
pub const fn from_uri(uri: Uri<S>) -> Self {
Self::new(Vector::new(), Headers::new(), uri)
}
#[inline]
pub const fn new(data: Vector<u8>, headers: Headers, uri: Uri<S>) -> Self {
Self { body: data, headers, uri }
}
#[inline]
pub const fn as_http2_request(&self, method: Method) -> Request<&Self> {
Request { method, msg_data: self }
}
#[inline]
pub const fn as_http2_request_mut(&mut self, method: Method) -> Request<&mut Self> {
Request { method, msg_data: self }
}
#[inline]
pub const fn as_http2_response(&self, status_code: StatusCode) -> Response<&Self> {
Response { msg_data: self, status_code }
}
#[inline]
pub const fn as_http2_response_mut(&mut self, status_code: StatusCode) -> Response<&mut Self> {
Response { msg_data: self, status_code }
}
#[inline]
pub const fn into_http2_request(self, method: Method) -> Request<Self> {
Request { method, msg_data: self }
}
#[inline]
pub const fn into_http2_response(self, status_code: StatusCode) -> Response<Self> {
Response { msg_data: self, status_code }
}
#[inline]
pub const fn parts_mut(&mut self) -> (&mut Vector<u8>, &mut Headers, &mut Uri<S>) {
(&mut self.body, &mut self.headers, &mut self.uri)
}
}
impl<S> MsgData for MsgBuffer<S>
where
S: Lease<str>,
{
type Body = Vector<u8>;
#[inline]
fn body(&self) -> &Self::Body {
&self.body
}
#[inline]
fn headers(&self) -> &Headers {
&self.headers
}
#[inline]
fn uri(&self) -> UriRef<'_> {
self.uri.lease().to_ref()
}
}
impl<S> MsgDataMut for MsgBuffer<S>
where
S: Clear + Lease<str>,
{
#[inline]
fn body_mut(&mut self) -> &mut Self::Body {
&mut self.body
}
#[inline]
fn clear(&mut self) {
self.body.clear();
self.headers.clear();
self.uri.clear();
}
#[inline]
fn clear_body_and_headers(&mut self) {
self.body.clear();
self.headers.clear();
}
#[inline]
fn headers_mut(&mut self) -> &mut Headers {
&mut self.headers
}
#[inline]
fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>) {
(&mut self.body, &mut self.headers, self.uri.lease().to_ref())
}
}
impl<S> Lease<[u8]> for MsgBuffer<S> {
#[inline]
fn lease(&self) -> &[u8] {
&self.body
}
}
impl<S> Lease<MsgBuffer<S>> for MsgBuffer<S> {
#[inline]
fn lease(&self) -> &MsgBuffer<S> {
self
}
}
impl<S> LeaseMut<MsgBuffer<S>> for MsgBuffer<S> {
#[inline]
fn lease_mut(&mut self) -> &mut MsgBuffer<S> {
self
}
}
impl<S> Debug for MsgBuffer<S>
where
S: Lease<str>,
{
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("MsgBuffer")
.field("body", &self.body)
.field("headers", &self.headers)
.field("uri", &self.uri)
.finish()
}
}
impl<S> Default for MsgBuffer<S>
where
S: Default + Lease<str>,
{
#[inline]
fn default() -> Self {
Self::from_uri(Uri::empty(S::default()))
}
}
impl<S> From<Vector<u8>> for MsgBuffer<S>
where
S: Default + Lease<str>,
{
#[inline]
fn from(from: Vector<u8>) -> Self {
Self { body: from, headers: Headers::new(), uri: Uri::empty(S::default()) }
}
}
#[cfg(feature = "std")]
impl<S> core::fmt::Write for MsgBuffer<S> {
#[inline]
fn write_str(&mut self, s: &str) -> core::fmt::Result {
self.body.extend_from_copyable_slice(s.as_bytes()).map_err(|_err| core::fmt::Error)
}
}
#[cfg(feature = "std")]
impl<S> std::io::Write for MsgBuffer<S> {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.body.write(buf)
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
self.body.flush()
}
}