Skip to content

Commit 26a35c2

Browse files
authored
Merge pull request #109 from http-rs/header-values
Replace Vec<HeaderValue> with HeaderValues
2 parents 2927208 + 80e39e1 commit 26a35c2

File tree

12 files changed

+234
-54
lines changed

12 files changed

+234
-54
lines changed

src/headers/header_value.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::fmt::{self, Display};
22
use std::str::FromStr;
33

4+
use crate::headers::HeaderValues;
45
use crate::Error;
56
use crate::{Cookie, Mime};
67

@@ -119,3 +120,13 @@ impl<'a> PartialEq<&String> for HeaderValue {
119120
&&self.inner == other
120121
}
121122
}
123+
124+
impl From<HeaderValues> for HeaderValue {
125+
fn from(mut other: HeaderValues) -> Self {
126+
other.inner.reverse();
127+
other
128+
.inner
129+
.pop()
130+
.expect("HeaderValues should contain at least one value")
131+
}
132+
}

src/headers/header_values.rs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
use crate::headers::{HeaderValue, Values};
2+
3+
use std::fmt::{self, Display};
4+
use std::iter::FromIterator;
5+
use std::ops::{Deref, DerefMut, Index};
6+
use std::slice::SliceIndex;
7+
8+
/// A list of `HeaderValue`s.
9+
///
10+
/// This always contains at least one header value.
11+
#[derive(Debug, Clone)]
12+
pub struct HeaderValues {
13+
pub(crate) inner: Vec<HeaderValue>,
14+
}
15+
16+
impl HeaderValues {
17+
/// Move all values from `other` into `self`, leaving `other` empty.
18+
pub fn append(&mut self, other: &mut Self) {
19+
self.inner.append(&mut other.inner)
20+
}
21+
22+
/// Returns a reference or a value depending on the type of index.
23+
pub fn get(&self, index: usize) -> Option<&HeaderValue> {
24+
self.inner.get(index)
25+
}
26+
27+
/// Returns a mutable reference or a value depending on the type of index.
28+
pub fn get_mut(&mut self, index: usize) -> Option<&mut HeaderValue> {
29+
self.inner.get_mut(index)
30+
}
31+
32+
/// Returns the last `HeaderValue`.
33+
pub fn last(&self) -> &HeaderValue {
34+
self.inner
35+
.last()
36+
.expect("HeaderValues must always contain at least one value")
37+
}
38+
39+
/// An iterator visiting all header values in arbitrary order.
40+
pub fn iter(&self) -> Values<'_> {
41+
Values::new_values(&self)
42+
}
43+
44+
// /// An iterator visiting all header values in arbitrary order, with mutable
45+
// /// references to the values.
46+
// pub fn iter_mut(&mut self) -> ValuesMut<'_> {
47+
// ValuesMut {
48+
// inner: self.headers.iter_mut(),
49+
// }
50+
// }
51+
}
52+
53+
impl<I: SliceIndex<[HeaderValue]>> Index<I> for HeaderValues {
54+
type Output = I::Output;
55+
56+
#[inline]
57+
fn index(&self, index: I) -> &Self::Output {
58+
Index::index(&self.inner, index)
59+
}
60+
}
61+
62+
impl FromIterator<HeaderValue> for HeaderValues {
63+
fn from_iter<I>(iter: I) -> HeaderValues
64+
where
65+
I: IntoIterator<Item = HeaderValue>,
66+
{
67+
let iter = iter.into_iter();
68+
let mut output = Vec::with_capacity(iter.size_hint().0);
69+
for v in iter {
70+
output.push(v);
71+
}
72+
HeaderValues { inner: output }
73+
}
74+
}
75+
76+
impl Display for HeaderValues {
77+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78+
let mut list = f.debug_list();
79+
for v in &self.inner {
80+
list.entry(&v);
81+
}
82+
list.finish()
83+
}
84+
}
85+
86+
impl PartialEq<str> for HeaderValues {
87+
fn eq(&self, other: &str) -> bool {
88+
self.inner[0] == other
89+
}
90+
}
91+
92+
impl<'a> PartialEq<&'a str> for HeaderValues {
93+
fn eq(&self, other: &&'a str) -> bool {
94+
&self.inner[0] == other
95+
}
96+
}
97+
98+
impl PartialEq<String> for HeaderValues {
99+
fn eq(&self, other: &String) -> bool {
100+
&self.inner[0] == other
101+
}
102+
}
103+
104+
impl<'a> PartialEq<&String> for HeaderValues {
105+
fn eq(&self, other: &&String) -> bool {
106+
&&self.inner[0] == other
107+
}
108+
}
109+
110+
impl From<HeaderValue> for HeaderValues {
111+
fn from(other: HeaderValue) -> Self {
112+
Self { inner: vec![other] }
113+
}
114+
}
115+
116+
impl AsRef<HeaderValue> for HeaderValues {
117+
fn as_ref(&self) -> &HeaderValue {
118+
&self.inner[0]
119+
}
120+
}
121+
122+
impl AsMut<HeaderValue> for HeaderValues {
123+
fn as_mut(&mut self) -> &mut HeaderValue {
124+
&mut self.inner[0]
125+
}
126+
}
127+
impl Deref for HeaderValues {
128+
type Target = HeaderValue;
129+
130+
fn deref(&self) -> &HeaderValue {
131+
&self.inner[0]
132+
}
133+
}
134+
135+
impl DerefMut for HeaderValues {
136+
fn deref_mut(&mut self) -> &mut HeaderValue {
137+
&mut self.inner[0]
138+
}
139+
}
140+
141+
impl<'a> IntoIterator for &'a HeaderValues {
142+
type Item = &'a HeaderValue;
143+
type IntoIter = Values<'a>;
144+
145+
#[inline]
146+
fn into_iter(self) -> Self::IntoIter {
147+
self.iter()
148+
}
149+
}

src/headers/into_iter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
use std::collections::hash_map;
22
use std::iter::Iterator;
33

4-
use crate::headers::{HeaderName, HeaderValue};
4+
use crate::headers::{HeaderName, HeaderValues};
55

66
/// An owning iterator over the entries of `Headers`.
77
#[derive(Debug)]
88
pub struct IntoIter {
9-
pub(super) inner: hash_map::IntoIter<HeaderName, Vec<HeaderValue>>,
9+
pub(super) inner: hash_map::IntoIter<HeaderName, HeaderValues>,
1010
}
1111

1212
impl Iterator for IntoIter {
13-
type Item = (HeaderName, Vec<HeaderValue>);
13+
type Item = (HeaderName, HeaderValues);
1414

1515
fn next(&mut self) -> Option<Self::Item> {
1616
self.inner.next()

src/headers/iter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
use std::collections::hash_map;
22
use std::iter::Iterator;
33

4-
use crate::headers::{HeaderName, HeaderValue};
4+
use crate::headers::{HeaderName, HeaderValues};
55

66
/// Iterator over the headers.
77
#[derive(Debug)]
88
pub struct Iter<'a> {
9-
pub(super) inner: hash_map::Iter<'a, HeaderName, Vec<HeaderValue>>,
9+
pub(super) inner: hash_map::Iter<'a, HeaderName, HeaderValues>,
1010
}
1111

1212
impl<'a> Iterator for Iter<'a> {
13-
type Item = (&'a HeaderName, &'a Vec<HeaderValue>);
13+
type Item = (&'a HeaderName, &'a HeaderValues);
1414

1515
fn next(&mut self) -> Option<Self::Item> {
1616
self.inner.next()

src/headers/iter_mut.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
use std::collections::hash_map;
22
use std::iter::Iterator;
33

4-
use crate::headers::{HeaderName, HeaderValue};
4+
use crate::headers::{HeaderName, HeaderValues};
55

66
/// Iterator over the headers.
77
#[derive(Debug)]
88
pub struct IterMut<'a> {
9-
pub(super) inner: hash_map::IterMut<'a, HeaderName, Vec<HeaderValue>>,
9+
pub(super) inner: hash_map::IterMut<'a, HeaderName, HeaderValues>,
1010
}
1111

1212
impl<'a> Iterator for IterMut<'a> {
13-
type Item = (&'a HeaderName, &'a mut Vec<HeaderValue>);
13+
type Item = (&'a HeaderName, &'a mut HeaderValues);
1414

1515
fn next(&mut self) -> Option<Self::Item> {
1616
self.inner.next()

src/headers/mod.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::iter::IntoIterator;
77
mod constants;
88
mod header_name;
99
mod header_value;
10+
mod header_values;
1011
mod into_iter;
1112
mod iter;
1213
mod iter_mut;
@@ -17,6 +18,7 @@ mod values;
1718
pub use constants::*;
1819
pub use header_name::HeaderName;
1920
pub use header_value::HeaderValue;
21+
pub use header_values::HeaderValues;
2022
pub use into_iter::IntoIter;
2123
pub use iter::Iter;
2224
pub use iter_mut::IterMut;
@@ -27,7 +29,7 @@ pub use values::Values;
2729
/// A collection of HTTP Headers.
2830
#[derive(Debug, Clone)]
2931
pub struct Headers {
30-
pub(crate) headers: HashMap<HeaderName, Vec<HeaderValue>>,
32+
pub(crate) headers: HashMap<HeaderName, HeaderValues>,
3133
}
3234

3335
impl Headers {
@@ -47,11 +49,11 @@ impl Headers {
4749
&mut self,
4850
name: impl TryInto<HeaderName>,
4951
values: impl ToHeaderValues,
50-
) -> crate::Result<Option<Vec<HeaderValue>>> {
52+
) -> crate::Result<Option<HeaderValues>> {
5153
let name = name
5254
.try_into()
5355
.map_err(|_| crate::format_err!("Could not convert into header name"))?;
54-
let values: Vec<HeaderValue> = values.to_header_values()?.collect();
56+
let values: HeaderValues = values.to_header_values()?.collect();
5557
Ok(self.headers.insert(name, values))
5658
}
5759

@@ -69,7 +71,7 @@ impl Headers {
6971
.map_err(|_| crate::format_err!("Could not convert into header name"))?;
7072
match self.get_mut(&name) {
7173
Some(headers) => {
72-
let mut values: Vec<HeaderValue> = values.to_header_values()?.collect();
74+
let mut values: HeaderValues = values.to_header_values()?.collect();
7375
headers.append(&mut values);
7476
}
7577
None => {
@@ -80,17 +82,17 @@ impl Headers {
8082
}
8183

8284
/// Get a reference to a header.
83-
pub fn get(&self, name: &HeaderName) -> Option<&Vec<HeaderValue>> {
85+
pub fn get(&self, name: &HeaderName) -> Option<&HeaderValues> {
8486
self.headers.get(name)
8587
}
8688

8789
/// Get a mutable reference to a header.
88-
pub fn get_mut(&mut self, name: &HeaderName) -> Option<&mut Vec<HeaderValue>> {
90+
pub fn get_mut(&mut self, name: &HeaderName) -> Option<&mut HeaderValues> {
8991
self.headers.get_mut(name)
9092
}
9193

9294
/// Remove a header.
93-
pub fn remove(&mut self, name: &HeaderName) -> Option<Vec<HeaderValue>> {
95+
pub fn remove(&mut self, name: &HeaderName) -> Option<HeaderValues> {
9496
self.headers.remove(name)
9597
}
9698

@@ -123,7 +125,7 @@ impl Headers {
123125
}
124126

125127
impl IntoIterator for Headers {
126-
type Item = (HeaderName, Vec<HeaderValue>);
128+
type Item = (HeaderName, HeaderValues);
127129
type IntoIter = IntoIter;
128130

129131
/// Returns a iterator of references over the remaining items.
@@ -136,7 +138,7 @@ impl IntoIterator for Headers {
136138
}
137139

138140
impl<'a> IntoIterator for &'a Headers {
139-
type Item = (&'a HeaderName, &'a Vec<HeaderValue>);
141+
type Item = (&'a HeaderName, &'a HeaderValues);
140142
type IntoIter = Iter<'a>;
141143

142144
#[inline]
@@ -146,7 +148,7 @@ impl<'a> IntoIterator for &'a Headers {
146148
}
147149

148150
impl<'a> IntoIterator for &'a mut Headers {
149-
type Item = (&'a HeaderName, &'a mut Vec<HeaderValue>);
151+
type Item = (&'a HeaderName, &'a mut HeaderValues);
150152
type IntoIter = IterMut<'a>;
151153

152154
#[inline]

src/headers/names.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::collections::hash_map;
22
use std::iter::Iterator;
33

4-
use crate::headers::{HeaderName, HeaderValue};
4+
use crate::headers::{HeaderName, HeaderValues};
55

66
/// Iterator over the headers.
77
#[derive(Debug)]
88
pub struct Names<'a> {
9-
pub(super) inner: hash_map::Keys<'a, HeaderName, Vec<HeaderValue>>,
9+
pub(super) inner: hash_map::Keys<'a, HeaderName, HeaderValues>,
1010
}
1111

1212
impl<'a> Iterator for Names<'a> {

0 commit comments

Comments
 (0)