#
http_body/
frame.rs

    1use http::HeaderMap;
    2
    3/// A frame of any kind related to an HTTP stream (body).
    4#[derive(Debug)]
    5pub struct Frame<T> {
    6    kind: Kind<T>,
    7}
    8
    9#[derive(Debug)]
    10enum Kind<T> {
    11    // The first two variants are "inlined" since they are undoubtedly
    12    // the most common. This saves us from having to allocate a
    13    // boxed trait object for them.
    14    Data(T),
    15    Trailers(HeaderMap),
    16    //Unknown(Box<dyn Frameish>),
    17}
    18
    19impl<T> Frame<T> {
    20    /// Create a DATA frame with the provided `Buf`.
    21    pub fn data(buf: T) -> Self {
    22        Self {
    23            kind: Kind::Data(buf),
    24        }
    25    }
    26
    27    /// Create a trailers frame.
    28    pub fn trailers(map: HeaderMap) -> Self {
    29        Self {
    30            kind: Kind::Trailers(map),
    31        }
    32    }
    33
    34    /// Maps this frame's data to a different type.
    35    pub fn map_data<F, D>(self, f: F) -> Frame<D>
    36    where
    37        F: FnOnce(T) -> D,
    38    {
    39        match self.kind {
    40            Kind::Data(data) => Frame {
    41                kind: Kind::Data(f(data)),
    42            },
    43            Kind::Trailers(trailers) => Frame {
    44                kind: Kind::Trailers(trailers),
    45            },
    46        }
    47    }
    48
    49    /// Returns whether this is a DATA frame.
    50    pub fn is_data(&self) -> bool {
    51        matches!(self.kind, Kind::Data(..))
    52    }
    53
    54    /// Consumes self into the buf of the DATA frame.
    55    ///
    56    /// Returns an [`Err`] containing the original [`Frame`] when frame is not a DATA frame.
    57    /// `Frame::is_data` can also be used to determine if the frame is a DATA frame.
    58    pub fn into_data(self) -> Result<T, Self> {
    59        match self.kind {
    60            Kind::Data(data) => Ok(data),
    61            _ => Err(self),
    62        }
    63    }
    64
    65    /// If this is a DATA frame, returns a reference to it.
    66    ///
    67    /// Returns `None` if not a DATA frame.
    68    pub fn data_ref(&self) -> Option<&T> {
    69        match self.kind {
    70            Kind::Data(ref data) => Some(data),
    71            _ => None,
    72        }
    73    }
    74
    75    /// If this is a DATA frame, returns a mutable reference to it.
    76    ///
    77    /// Returns `None` if not a DATA frame.
    78    pub fn data_mut(&mut self) -> Option<&mut T> {
    79        match self.kind {
    80            Kind::Data(ref mut data) => Some(data),
    81            _ => None,
    82        }
    83    }
    84
    85    /// Returns whether this is a trailers frame.
    86    pub fn is_trailers(&self) -> bool {
    87        matches!(self.kind, Kind::Trailers(..))
    88    }
    89
    90    /// Consumes self into the buf of the trailers frame.
    91    ///
    92    /// Returns an [`Err`] containing the original [`Frame`] when frame is not a trailers frame.
    93    /// `Frame::is_trailers` can also be used to determine if the frame is a trailers frame.
    94    pub fn into_trailers(self) -> Result<HeaderMap, Self> {
    95        match self.kind {
    96            Kind::Trailers(trailers) => Ok(trailers),
    97            _ => Err(self),
    98        }
    99    }
    100
    101    /// If this is a trailers frame, returns a reference to it.
    102    ///
    103    /// Returns `None` if not a trailers frame.
    104    pub fn trailers_ref(&self) -> Option<&HeaderMap> {
    105        match self.kind {
    106            Kind::Trailers(ref trailers) => Some(trailers),
    107            _ => None,
    108        }
    109    }
    110
    111    /// If this is a trailers frame, returns a mutable reference to it.
    112    ///
    113    /// Returns `None` if not a trailers frame.
    114    pub fn trailers_mut(&mut self) -> Option<&mut HeaderMap> {
    115        match self.kind {
    116            Kind::Trailers(ref mut trailers) => Some(trailers),
    117            _ => None,
    118        }
    119    }
    120}