http_types/headers/
header_value.rs
1use std::convert::TryFrom;
2use std::fmt::{self, Debug, Display};
3use std::str::FromStr;
4
5use crate::headers::HeaderValues;
6#[cfg(feature = "cookies")]
7use crate::Cookie;
8use crate::Error;
9use crate::Mime;
10
11#[derive(Clone, Eq, PartialEq, Hash)]
13pub struct HeaderValue {
14 inner: String,
15}
16
17impl HeaderValue {
18 pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, Error> {
24 crate::ensure!(bytes.is_ascii(), "Bytes should be valid ASCII");
25
26 let string = unsafe { String::from_utf8_unchecked(bytes) };
28 Ok(Self { inner: string })
29 }
30
31 pub unsafe fn from_bytes_unchecked(bytes: Vec<u8>) -> Self {
41 let string = String::from_utf8_unchecked(bytes);
42 Self { inner: string }
43 }
44
45 pub fn as_str(&self) -> &str {
47 &self.inner
48 }
49}
50
51impl From<Mime> for HeaderValue {
52 fn from(mime: Mime) -> Self {
53 HeaderValue {
54 inner: format!("{}", mime),
55 }
56 }
57}
58
59#[cfg(feature = "cookies")]
60impl From<Cookie<'_>> for HeaderValue {
61 fn from(cookie: Cookie<'_>) -> Self {
62 HeaderValue {
63 inner: cookie.to_string(),
64 }
65 }
66}
67
68impl From<&Mime> for HeaderValue {
69 fn from(mime: &Mime) -> Self {
70 HeaderValue {
71 inner: format!("{}", mime),
72 }
73 }
74}
75
76impl FromStr for HeaderValue {
77 type Err = Error;
78
79 fn from_str(s: &str) -> Result<Self, Self::Err> {
83 crate::ensure!(s.is_ascii(), "String slice should be valid ASCII");
84 Ok(Self {
85 inner: String::from(s),
86 })
87 }
88}
89
90impl<'a> TryFrom<&'a str> for HeaderValue {
91 type Error = Error;
92
93 fn try_from(value: &'a str) -> Result<Self, Self::Error> {
94 Self::from_str(value)
95 }
96}
97
98impl Debug for HeaderValue {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 write!(f, "{:?}", self.inner)
101 }
102}
103
104impl Display for HeaderValue {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 write!(f, "{}", self.inner)
107 }
108}
109
110impl PartialEq<str> for HeaderValue {
111 fn eq(&self, other: &str) -> bool {
112 self.inner == other
113 }
114}
115
116impl<'a> PartialEq<&'a str> for HeaderValue {
117 fn eq(&self, other: &&'a str) -> bool {
118 &self.inner == other
119 }
120}
121
122impl PartialEq<String> for HeaderValue {
123 fn eq(&self, other: &String) -> bool {
124 &self.inner == other
125 }
126}
127
128impl<'a> PartialEq<&String> for HeaderValue {
129 fn eq(&self, other: &&String) -> bool {
130 &&self.inner == other
131 }
132}
133
134impl From<HeaderValues> for HeaderValue {
135 fn from(mut other: HeaderValues) -> Self {
136 other.inner.reverse();
137 other
138 .inner
139 .pop()
140 .expect("HeaderValues should contain at least one value")
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_debug() {
150 let header_value = HeaderValue::from_str("foo0").unwrap();
151 assert_eq!(format!("{:?}", header_value), "\"foo0\"");
152 }
153}