actix_http/header/
into_pair.rs

1//! [`TryIntoHeaderPair`] trait and implementations.
2
3use super::{
4    Header, HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, TryIntoHeaderValue,
5};
6use crate::error::HttpError;
7
8/// An interface for types that can be converted into a [`HeaderName`] + [`HeaderValue`] pair for
9/// insertion into a [`HeaderMap`].
10///
11/// [`HeaderMap`]: super::HeaderMap
12pub trait TryIntoHeaderPair: Sized {
13    type Error: Into<HttpError>;
14
15    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
16}
17
18#[derive(Debug)]
19pub enum InvalidHeaderPart {
20    Name(InvalidHeaderName),
21    Value(InvalidHeaderValue),
22}
23
24impl From<InvalidHeaderPart> for HttpError {
25    fn from(part_err: InvalidHeaderPart) -> Self {
26        match part_err {
27            InvalidHeaderPart::Name(err) => err.into(),
28            InvalidHeaderPart::Value(err) => err.into(),
29        }
30    }
31}
32
33impl<V> TryIntoHeaderPair for (HeaderName, V)
34where
35    V: TryIntoHeaderValue,
36    V::Error: Into<InvalidHeaderValue>,
37{
38    type Error = InvalidHeaderPart;
39
40    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
41        let (name, value) = self;
42        let value = value
43            .try_into_value()
44            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
45        Ok((name, value))
46    }
47}
48
49impl<V> TryIntoHeaderPair for (&HeaderName, V)
50where
51    V: TryIntoHeaderValue,
52    V::Error: Into<InvalidHeaderValue>,
53{
54    type Error = InvalidHeaderPart;
55
56    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
57        let (name, value) = self;
58        let value = value
59            .try_into_value()
60            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
61        Ok((name.clone(), value))
62    }
63}
64
65impl<V> TryIntoHeaderPair for (&[u8], V)
66where
67    V: TryIntoHeaderValue,
68    V::Error: Into<InvalidHeaderValue>,
69{
70    type Error = InvalidHeaderPart;
71
72    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
73        let (name, value) = self;
74        let name = HeaderName::try_from(name).map_err(InvalidHeaderPart::Name)?;
75        let value = value
76            .try_into_value()
77            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
78        Ok((name, value))
79    }
80}
81
82impl<V> TryIntoHeaderPair for (&str, V)
83where
84    V: TryIntoHeaderValue,
85    V::Error: Into<InvalidHeaderValue>,
86{
87    type Error = InvalidHeaderPart;
88
89    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
90        let (name, value) = self;
91        let name = HeaderName::try_from(name).map_err(InvalidHeaderPart::Name)?;
92        let value = value
93            .try_into_value()
94            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
95        Ok((name, value))
96    }
97}
98
99impl<V> TryIntoHeaderPair for (String, V)
100where
101    V: TryIntoHeaderValue,
102    V::Error: Into<InvalidHeaderValue>,
103{
104    type Error = InvalidHeaderPart;
105
106    #[inline]
107    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
108        let (name, value) = self;
109        (name.as_str(), value).try_into_pair()
110    }
111}
112
113impl<T: Header> TryIntoHeaderPair for T {
114    type Error = <T as TryIntoHeaderValue>::Error;
115
116    #[inline]
117    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
118        Ok((T::name(), self.try_into_value()?))
119    }
120}