use bytes::BytesMut;
use tokio_util::codec::{Decoder, Encoder};
use crate::{
CodecError, Method, Protocol, Version,
header::{FieldIter, HeaderField, HeaderFieldValue, Iter},
ttpkit::request::{
RequestHeader as GenericRequestHeader, RequestHeaderBuilder as GenericRequestHeaderBuilder,
RequestHeaderDecoder as GenericRequestHeaderDecoder,
RequestHeaderEncoder as GenericRequestHeaderEncoder,
},
};
pub use crate::ttpkit::request::{RequestHeaderDecoderOptions, RequestPath};
#[derive(Clone)]
pub struct RequestHeader {
inner: GenericRequestHeader<Protocol, Version, Method>,
}
impl RequestHeader {
#[inline]
pub(crate) const fn new(header: GenericRequestHeader<Protocol, Version, Method>) -> Self {
Self { inner: header }
}
#[inline]
pub fn method(&self) -> Method {
*self.inner.method()
}
#[inline]
pub fn version(&self) -> Version {
*self.inner.version()
}
#[inline]
pub fn path(&self) -> &RequestPath {
self.inner.path()
}
#[inline]
pub fn get_all_header_fields(&self) -> Iter<'_> {
self.inner.get_all_header_fields()
}
pub fn get_header_fields<'a, N>(&'a self, name: &'a N) -> FieldIter<'a>
where
N: AsRef<[u8]> + ?Sized,
{
self.inner.get_header_fields(name)
}
pub fn get_header_field<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderField>
where
N: AsRef<[u8]> + ?Sized,
{
self.inner.get_header_field(name)
}
pub fn get_header_field_value<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderFieldValue>
where
N: AsRef<[u8]> + ?Sized,
{
self.inner.get_header_field_value(name)
}
}
#[derive(Clone)]
pub struct RequestBuilder {
inner: GenericRequestHeaderBuilder<Protocol, Version, Method>,
}
impl RequestBuilder {
#[inline]
const fn new(version: Version, method: Method, path: RequestPath) -> Self {
Self {
inner: GenericRequestHeader::builder(Protocol, version, method, path),
}
}
#[inline]
pub fn set_version(mut self, version: Version) -> Self {
self.inner = self.inner.set_version(version);
self
}
#[inline]
pub fn set_method(mut self, method: Method) -> Self {
self.inner = self.inner.set_method(method);
self
}
#[inline]
pub fn set_path(mut self, path: RequestPath) -> Self {
self.inner = self.inner.set_path(path);
self
}
pub fn set_header_field<T>(mut self, field: T) -> Self
where
T: Into<HeaderField>,
{
self.inner = self.inner.set_header_field(field);
self
}
pub fn add_header_field<T>(mut self, field: T) -> Self
where
T: Into<HeaderField>,
{
self.inner = self.inner.add_header_field(field);
self
}
pub fn remove_header_fields<N>(mut self, name: &N) -> Self
where
N: AsRef<[u8]> + ?Sized,
{
self.inner = self.inner.remove_header_fields(name);
self
}
#[inline]
pub fn header(self) -> RequestHeader {
RequestHeader::new(self.inner.build())
}
pub fn body<B>(self, body: B) -> Request<B> {
Request::new(self.header(), body)
}
}
impl From<RequestHeader> for RequestBuilder {
#[inline]
fn from(header: RequestHeader) -> Self {
Self {
inner: header.inner.into(),
}
}
}
pub struct Request<B> {
header: RequestHeader,
body: B,
}
impl Request<()> {
#[inline]
pub const fn builder(version: Version, method: Method, path: RequestPath) -> RequestBuilder {
RequestBuilder::new(version, method, path)
}
}
impl<B> Request<B> {
pub(crate) const fn new(header: RequestHeader, body: B) -> Self {
Self { header, body }
}
#[inline]
pub fn header(&self) -> &RequestHeader {
&self.header
}
#[inline]
pub fn method(&self) -> Method {
self.header.method()
}
#[inline]
pub fn version(&self) -> Version {
self.header.version()
}
#[inline]
pub fn path(&self) -> &RequestPath {
self.header.path()
}
#[inline]
pub fn get_all_header_fields(&self) -> Iter<'_> {
self.header.get_all_header_fields()
}
pub fn get_header_fields<'a, N>(&'a self, name: &'a N) -> FieldIter<'a>
where
N: AsRef<[u8]> + ?Sized,
{
self.header.get_header_fields(name)
}
pub fn get_header_field<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderField>
where
N: AsRef<[u8]> + ?Sized,
{
self.header.get_header_field(name)
}
pub fn get_header_field_value<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderFieldValue>
where
N: AsRef<[u8]> + ?Sized,
{
self.header.get_header_field_value(name)
}
#[inline]
pub fn body(self) -> B {
self.body
}
#[inline]
pub fn deconstruct(self) -> (RequestHeader, B) {
(self.header, self.body)
}
}
pub struct RequestHeaderDecoder {
inner: GenericRequestHeaderDecoder<Protocol, Version, Method>,
}
impl RequestHeaderDecoder {
#[inline]
pub fn new(options: RequestHeaderDecoderOptions) -> Self {
Self {
inner: GenericRequestHeaderDecoder::new(options),
}
}
#[inline]
pub fn reset(&mut self) {
self.inner.reset();
}
pub fn decode(&mut self, data: &mut BytesMut) -> Result<Option<RequestHeader>, CodecError> {
let res = self.inner.decode(data)?.map(RequestHeader::new);
Ok(res)
}
pub fn decode_eof(&mut self, data: &mut BytesMut) -> Result<Option<RequestHeader>, CodecError> {
let res = self.inner.decode_eof(data)?.map(RequestHeader::new);
Ok(res)
}
}
impl Decoder for RequestHeaderDecoder {
type Item = RequestHeader;
type Error = CodecError;
#[inline]
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
Self::decode(self, buf)
}
#[inline]
fn decode_eof(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
Self::decode_eof(self, buf)
}
}
pub struct RequestHeaderEncoder {
inner: GenericRequestHeaderEncoder,
}
impl RequestHeaderEncoder {
#[inline]
pub const fn new() -> Self {
Self {
inner: GenericRequestHeaderEncoder::new(),
}
}
#[inline]
pub fn encode(&mut self, header: &RequestHeader, dst: &mut BytesMut) {
self.inner.encode(&header.inner, dst);
}
}
impl Default for RequestHeaderEncoder {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl Encoder<&RequestHeader> for RequestHeaderEncoder {
type Error = CodecError;
#[inline]
fn encode(&mut self, header: &RequestHeader, dst: &mut BytesMut) -> Result<(), Self::Error> {
Self::encode(self, header, dst);
Ok(())
}
}