use super::*;
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use primitives::RawBytes;
#[cfg(not(feature = "alloc"))]
pub type Header<O, B> = InlineHeader<O, B>;
#[cfg(feature = "alloc")]
pub type Header<O, B> = BoxedHeader<O, B>;
pub type HeaderOf<T, B> = Header<T, <T as HasView<B>>::ViewType>;
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum InlineHeader<O, B> {
Repr(O),
Raw(B),
}
#[cfg(feature = "alloc")]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum BoxedHeader<O, B> {
#[cfg(feature = "alloc")]
Repr(Box<O>),
Raw(B),
}
#[cfg(feature = "alloc")]
impl<O, B> From<InlineHeader<O, B>> for BoxedHeader<O, B> {
fn from(value: InlineHeader<O, B>) -> Self {
match value {
InlineHeader::Repr(o) => Self::Repr(o.into()),
InlineHeader::Raw(b) => Self::Raw(b),
}
}
}
#[cfg(feature = "alloc")]
impl<O, B> From<BoxedHeader<O, B>> for InlineHeader<O, B> {
fn from(value: BoxedHeader<O, B>) -> Self {
match value {
BoxedHeader::Repr(o) => Self::Repr(*o),
BoxedHeader::Raw(b) => Self::Raw(b),
}
}
}
#[cfg(feature = "alloc")]
impl<O, B> BoxedHeader<O, B> {
pub fn repr(&self) -> Option<&O> {
match self {
Self::Repr(o) => Some(o),
_ => None,
}
}
pub fn repr_mut(&mut self) -> Option<&mut O> {
match self {
Self::Repr(o) => Some(o),
_ => None,
}
}
pub fn raw(&self) -> Option<&B> {
match self {
Self::Raw(b) => Some(b),
_ => None,
}
}
pub fn raw_mut(&mut self) -> Option<&mut B> {
match self {
Self::Raw(b) => Some(b),
_ => None,
}
}
}
#[cfg(feature = "alloc")]
impl<
O: NextLayer + Clone,
B: NextLayer<Denom = O::Denom, Hint = O::Hint> + ToOwnedPacket<Target = O>,
> ToOwnedPacket for BoxedHeader<O, B>
{
type Target = O;
fn to_owned(&self, hint: Option<Self::Hint>) -> ParseResult<Self::Target> {
match self {
Header::Repr(o) => Ok(*o.clone()),
Header::Raw(v) => v.to_owned(hint),
}
}
}
#[cfg(feature = "alloc")]
impl<B: ByteSlice, T> From<&BoxedHeader<Vec<T>, RawBytes<B>>> for Vec<T>
where
T: FromBytes + IntoBytes + KnownLayout + Immutable + Clone,
{
fn from(value: &Header<Vec<T>, RawBytes<B>>) -> Self {
match value {
Header::Repr(v) => v.deref().clone(),
Header::Raw(v) => {
<[T]>::ref_from_bytes(v.as_ref()).unwrap().to_vec()
}
}
}
}
#[cfg(feature = "alloc")]
impl<O: HasView<V, ViewType = B>, B, V> HasView<V> for BoxedHeader<O, B> {
type ViewType = B;
}
#[cfg(feature = "alloc")]
impl<O, B> HasRepr for BoxedHeader<O, B> {
type ReprType = O;
}
#[cfg(feature = "alloc")]
impl<O, B> HeaderLen for BoxedHeader<O, B>
where
O: HeaderLen,
B: HeaderLen,
{
const MINIMUM_LENGTH: usize = O::MINIMUM_LENGTH;
#[inline]
fn packet_length(&self) -> usize {
match self {
Self::Repr(o) => o.packet_length(),
Self::Raw(b) => b.packet_length(),
}
}
}
#[cfg(feature = "alloc")]
impl<
V: SplitByteSlice,
B: HeaderParse<V> + HasRepr + NextLayer + Into<Self>,
> HeaderParse<V> for BoxedHeader<B::ReprType, B>
where
B: NextLayer,
B::ReprType: NextLayer<Denom = B::Denom, Hint = B::Hint>,
{
#[inline]
fn parse_choice(
from: V,
hint: Option<Self::Hint>,
) -> ParseResult<Success<Self, V>> {
<B as HeaderParse<V>>::parse_choice(from, hint)
.map(|(val, hint, remainder)| (val.into(), hint, remainder))
}
}
#[cfg(feature = "alloc")]
impl<O: NextLayer, B> NextLayer for BoxedHeader<O, B>
where
B: NextLayer<Denom = O::Denom, Hint = O::Hint>,
{
type Denom = O::Denom;
type Hint = O::Hint;
#[inline]
fn next_layer_choice(
&self,
hint: Option<Self::Hint>,
) -> Option<Self::Denom> {
match self {
Self::Repr(v) => v.next_layer_choice(hint),
Self::Raw(v) => v.next_layer_choice(hint),
}
}
}
#[cfg(feature = "alloc")]
unsafe impl<O: EmitDoesNotRelyOnBufContents, B: EmitDoesNotRelyOnBufContents>
EmitDoesNotRelyOnBufContents for BoxedHeader<O, B>
{
}
#[cfg(feature = "alloc")]
impl<O: Emit, B: Emit> Emit for BoxedHeader<O, B> {
#[inline]
fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize {
match self {
Self::Repr(o) => o.emit_raw(buf),
Self::Raw(b) => b.emit_raw(buf),
}
}
#[inline]
fn needs_emit(&self) -> bool {
match self {
Self::Repr(_) => true,
Self::Raw(b) => b.needs_emit(),
}
}
}
impl<O, B> InlineHeader<O, B> {
pub fn repr(&self) -> Option<&O> {
match self {
Self::Repr(o) => Some(o),
_ => None,
}
}
pub fn repr_mut(&mut self) -> Option<&mut O> {
match self {
Self::Repr(o) => Some(o),
_ => None,
}
}
pub fn raw(&self) -> Option<&B> {
match self {
Self::Raw(b) => Some(b),
_ => None,
}
}
pub fn raw_mut(&mut self) -> Option<&mut B> {
match self {
Self::Raw(b) => Some(b),
_ => None,
}
}
}
impl<
O: NextLayer + Clone,
B: NextLayer<Denom = O::Denom, Hint = O::Hint> + ToOwnedPacket<Target = O>,
> ToOwnedPacket for InlineHeader<O, B>
{
type Target = O;
fn to_owned(&self, hint: Option<Self::Hint>) -> ParseResult<Self::Target> {
match self {
Self::Repr(o) => Ok(o.clone()),
Self::Raw(v) => v.to_owned(hint),
}
}
}
impl<O: HasView<V, ViewType = B>, B, V> HasView<V> for InlineHeader<O, B> {
type ViewType = B;
}
impl<O, B> HasRepr for InlineHeader<O, B> {
type ReprType = O;
}
impl<O, B> HeaderLen for InlineHeader<O, B>
where
O: HeaderLen,
B: HeaderLen,
{
const MINIMUM_LENGTH: usize = O::MINIMUM_LENGTH;
#[inline]
fn packet_length(&self) -> usize {
match self {
Self::Repr(o) => o.packet_length(),
Self::Raw(b) => b.packet_length(),
}
}
}
impl<
V: SplitByteSlice,
B: HeaderParse<V> + HasRepr + NextLayer + Into<Self>,
> HeaderParse<V> for InlineHeader<B::ReprType, B>
where
B: NextLayer,
B::ReprType: NextLayer<Denom = B::Denom, Hint = B::Hint>,
{
#[inline]
fn parse_choice(
from: V,
hint: Option<Self::Hint>,
) -> ParseResult<Success<Self, V>> {
<B as HeaderParse<V>>::parse_choice(from, hint)
.map(|(val, hint, remainder)| (val.into(), hint, remainder))
}
}
impl<O: NextLayer, B> NextLayer for InlineHeader<O, B>
where
B: NextLayer<Denom = O::Denom, Hint = O::Hint>,
{
type Denom = O::Denom;
type Hint = O::Hint;
#[inline]
fn next_layer_choice(
&self,
hint: Option<Self::Hint>,
) -> Option<Self::Denom> {
match self {
Self::Repr(v) => v.next_layer_choice(hint),
Self::Raw(v) => v.next_layer_choice(hint),
}
}
}
unsafe impl<O: EmitDoesNotRelyOnBufContents, B: EmitDoesNotRelyOnBufContents>
EmitDoesNotRelyOnBufContents for InlineHeader<O, B>
{
}
impl<O: Emit, B: Emit> Emit for InlineHeader<O, B> {
#[inline]
fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize {
match self {
Self::Repr(o) => o.emit_raw(buf),
Self::Raw(b) => b.emit_raw(buf),
}
}
#[inline]
fn needs_emit(&self) -> bool {
match self {
Self::Repr(_) => true,
Self::Raw(b) => b.needs_emit(),
}
}
}