Skip to content

Commit 62f6cd8

Browse files
committed
Change HeaderMap::entry to no longer return a Result
- Only types that implement `IntoHeaderName` can now be passed to `entry`, though they still are lazily cloned. - Adds `HeaderMap::try_entry` that works as before, returning a `Result` if the key isn't a valid `HeaderName`. This is a breaking change. Closes #267
1 parent 5e395ef commit 62f6cd8

File tree

2 files changed

+68
-34
lines changed

2 files changed

+68
-34
lines changed

src/header/map.rs

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -998,19 +998,34 @@ impl<T> HeaderMap<T> {
998998
/// ];
999999
///
10001000
/// for &header in headers {
1001-
/// let counter = map.entry(header).unwrap().or_insert(0);
1001+
/// let counter = map.entry(header).or_insert(0);
10021002
/// *counter += 1;
10031003
/// }
10041004
///
10051005
/// assert_eq!(map["content-length"], 2);
10061006
/// assert_eq!(map["x-hello"], 1);
10071007
/// ```
1008-
pub fn entry<K>(&mut self, key: K) -> Result<Entry<T>, InvalidHeaderName>
1009-
where K: AsHeaderName,
1008+
pub fn entry<K>(&mut self, key: K) -> Entry<T>
1009+
where K: IntoHeaderName,
10101010
{
10111011
key.entry(self)
10121012
}
10131013

1014+
/// Gets the given key's corresponding entry in the map for in-place
1015+
/// manipulation.
1016+
///
1017+
/// # Errors
1018+
///
1019+
/// This method differs from `entry` by allowing types that may not be
1020+
/// valid `HeaderName`s to passed as the key (such as `String`). If they
1021+
/// do not parse as a valid `HeaderName`, this returns an
1022+
/// `InvalidHeaderName` error.
1023+
pub fn try_entry<K>(&mut self, key: K) -> Result<Entry<T>, InvalidHeaderName>
1024+
where K: AsHeaderName,
1025+
{
1026+
key.try_entry(self)
1027+
}
1028+
10141029
fn entry2<K>(&mut self, key: K) -> Entry<T>
10151030
where K: Hash + Into<HeaderName>,
10161031
HeaderName: PartialEq<K>,
@@ -2146,7 +2161,6 @@ impl<'a, T> Entry<'a, T> {
21462161
///
21472162
/// for &header in headers {
21482163
/// let counter = map.entry(header)
2149-
/// .expect("valid header names")
21502164
/// .or_insert(0);
21512165
/// *counter += 1;
21522166
/// }
@@ -2177,7 +2191,7 @@ impl<'a, T> Entry<'a, T> {
21772191
/// # use http::HeaderMap;
21782192
/// let mut map = HeaderMap::new();
21792193
///
2180-
/// let res = map.entry("x-hello").unwrap()
2194+
/// let res = map.entry("x-hello")
21812195
/// .or_insert_with(|| "world".parse().unwrap());
21822196
///
21832197
/// assert_eq!(res, "world");
@@ -2192,7 +2206,6 @@ impl<'a, T> Entry<'a, T> {
21922206
/// map.insert(HOST, "world".parse().unwrap());
21932207
///
21942208
/// let res = map.entry("host")
2195-
/// .expect("host is a valid string")
21962209
/// .or_insert_with(|| unreachable!());
21972210
///
21982211
///
@@ -2215,7 +2228,7 @@ impl<'a, T> Entry<'a, T> {
22152228
/// # use http::HeaderMap;
22162229
/// let mut map = HeaderMap::new();
22172230
///
2218-
/// assert_eq!(map.entry("x-hello").unwrap().key(), "x-hello");
2231+
/// assert_eq!(map.entry("x-hello").key(), "x-hello");
22192232
/// ```
22202233
pub fn key(&self) -> &HeaderName {
22212234
use self::Entry::*;
@@ -2238,7 +2251,7 @@ impl<'a, T> VacantEntry<'a, T> {
22382251
/// # use http::HeaderMap;
22392252
/// let mut map = HeaderMap::new();
22402253
///
2241-
/// assert_eq!(map.entry("x-hello").unwrap().key().as_str(), "x-hello");
2254+
/// assert_eq!(map.entry("x-hello").key().as_str(), "x-hello");
22422255
/// ```
22432256
pub fn key(&self) -> &HeaderName {
22442257
&self.key
@@ -2252,7 +2265,7 @@ impl<'a, T> VacantEntry<'a, T> {
22522265
/// # use http::header::{HeaderMap, Entry};
22532266
/// let mut map = HeaderMap::new();
22542267
///
2255-
/// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
2268+
/// if let Entry::Vacant(v) = map.entry("x-hello") {
22562269
/// assert_eq!(v.into_key().as_str(), "x-hello");
22572270
/// }
22582271
/// ```
@@ -2271,7 +2284,7 @@ impl<'a, T> VacantEntry<'a, T> {
22712284
/// # use http::header::{HeaderMap, Entry};
22722285
/// let mut map = HeaderMap::new();
22732286
///
2274-
/// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
2287+
/// if let Entry::Vacant(v) = map.entry("x-hello") {
22752288
/// v.insert("world".parse().unwrap());
22762289
/// }
22772290
///
@@ -2300,7 +2313,7 @@ impl<'a, T> VacantEntry<'a, T> {
23002313
/// # use http::header::*;
23012314
/// let mut map = HeaderMap::new();
23022315
///
2303-
/// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
2316+
/// if let Entry::Vacant(v) = map.entry("x-hello") {
23042317
/// let mut e = v.insert_entry("world".parse().unwrap());
23052318
/// e.insert("world2".parse().unwrap());
23062319
/// }
@@ -2618,7 +2631,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
26182631
/// let mut map = HeaderMap::new();
26192632
/// map.insert(HOST, "world".parse().unwrap());
26202633
///
2621-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2634+
/// if let Entry::Occupied(e) = map.entry("host") {
26222635
/// assert_eq!("host", e.key());
26232636
/// }
26242637
/// ```
@@ -2641,7 +2654,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
26412654
/// let mut map = HeaderMap::new();
26422655
/// map.insert(HOST, "hello.world".parse().unwrap());
26432656
///
2644-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2657+
/// if let Entry::Occupied(mut e) = map.entry("host") {
26452658
/// assert_eq!(e.get(), &"hello.world");
26462659
///
26472660
/// e.append("hello.earth".parse().unwrap());
@@ -2668,7 +2681,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
26682681
/// let mut map = HeaderMap::default();
26692682
/// map.insert(HOST, "hello.world".to_string());
26702683
///
2671-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2684+
/// if let Entry::Occupied(mut e) = map.entry("host") {
26722685
/// e.get_mut().push_str("-2");
26732686
/// assert_eq!(e.get(), &"hello.world-2");
26742687
/// }
@@ -2694,7 +2707,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
26942707
/// map.insert(HOST, "hello.world".to_string());
26952708
/// map.append(HOST, "hello.earth".to_string());
26962709
///
2697-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2710+
/// if let Entry::Occupied(e) = map.entry("host") {
26982711
/// e.into_mut().push_str("-2");
26992712
/// }
27002713
///
@@ -2716,7 +2729,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27162729
/// let mut map = HeaderMap::new();
27172730
/// map.insert(HOST, "hello.world".parse().unwrap());
27182731
///
2719-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2732+
/// if let Entry::Occupied(mut e) = map.entry("host") {
27202733
/// let mut prev = e.insert("earth".parse().unwrap());
27212734
/// assert_eq!("hello.world", prev);
27222735
/// }
@@ -2740,7 +2753,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27402753
/// map.insert(HOST, "world".parse().unwrap());
27412754
/// map.append(HOST, "world2".parse().unwrap());
27422755
///
2743-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2756+
/// if let Entry::Occupied(mut e) = map.entry("host") {
27442757
/// let mut prev = e.insert_mult("earth".parse().unwrap());
27452758
/// assert_eq!("world", prev.next().unwrap());
27462759
/// assert_eq!("world2", prev.next().unwrap());
@@ -2765,7 +2778,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27652778
/// let mut map = HeaderMap::new();
27662779
/// map.insert(HOST, "world".parse().unwrap());
27672780
///
2768-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2781+
/// if let Entry::Occupied(mut e) = map.entry("host") {
27692782
/// e.append("earth".parse().unwrap());
27702783
/// }
27712784
///
@@ -2792,7 +2805,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27922805
/// let mut map = HeaderMap::new();
27932806
/// map.insert(HOST, "world".parse().unwrap());
27942807
///
2795-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2808+
/// if let Entry::Occupied(e) = map.entry("host") {
27962809
/// let mut prev = e.remove();
27972810
/// assert_eq!("world", prev);
27982811
/// }
@@ -2816,7 +2829,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28162829
/// let mut map = HeaderMap::new();
28172830
/// map.insert(HOST, "world".parse().unwrap());
28182831
///
2819-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2832+
/// if let Entry::Occupied(e) = map.entry("host") {
28202833
/// let (key, mut prev) = e.remove_entry();
28212834
/// assert_eq!("host", key.as_str());
28222835
/// assert_eq!("world", prev);
@@ -2861,7 +2874,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28612874
/// map.insert(HOST, "world".parse().unwrap());
28622875
/// map.append(HOST, "earth".parse().unwrap());
28632876
///
2864-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2877+
/// if let Entry::Occupied(e) = map.entry("host") {
28652878
/// let mut iter = e.iter();
28662879
/// assert_eq!(&"world", iter.next().unwrap());
28672880
/// assert_eq!(&"earth", iter.next().unwrap());
@@ -2885,7 +2898,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28852898
/// map.insert(HOST, "world".to_string());
28862899
/// map.append(HOST, "earth".to_string());
28872900
///
2888-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2901+
/// if let Entry::Occupied(mut e) = map.entry("host") {
28892902
/// for e in e.iter_mut() {
28902903
/// e.push_str("-boop");
28912904
/// }
@@ -3105,7 +3118,7 @@ fn hash_elem_using<K: ?Sized>(danger: &Danger, k: &K) -> HashValue
31053118

31063119

31073120
mod into_header_name {
3108-
use super::{HdrName, HeaderMap, HeaderName};
3121+
use super::{Entry, HdrName, HeaderMap, HeaderName};
31093122

31103123
/// A marker trait used to identify values that can be used as insert keys
31113124
/// to a `HeaderMap`.
@@ -3125,6 +3138,9 @@ mod into_header_name {
31253138

31263139
#[doc(hidden)]
31273140
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool;
3141+
3142+
#[doc(hidden)]
3143+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T>;
31283144
}
31293145

31303146
// ==== impls ====
@@ -3141,6 +3157,12 @@ mod into_header_name {
31413157
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
31423158
map.append2(self, val)
31433159
}
3160+
3161+
#[doc(hidden)]
3162+
#[inline]
3163+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T> {
3164+
map.entry2(self)
3165+
}
31443166
}
31453167

31463168
impl IntoHeaderName for HeaderName {}
@@ -3156,6 +3178,12 @@ mod into_header_name {
31563178
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
31573179
map.append2(self, val)
31583180
}
3181+
3182+
#[doc(hidden)]
3183+
#[inline]
3184+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T> {
3185+
map.entry2(self)
3186+
}
31593187
}
31603188

31613189
impl<'a> IntoHeaderName for &'a HeaderName {}
@@ -3171,6 +3199,12 @@ mod into_header_name {
31713199
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
31723200
HdrName::from_static(self, move |hdr| map.append2(hdr, val))
31733201
}
3202+
3203+
#[doc(hidden)]
3204+
#[inline]
3205+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T> {
3206+
HdrName::from_static(self, move |hdr| map.entry2(hdr))
3207+
}
31743208
}
31753209

31763210
impl IntoHeaderName for &'static str {}
@@ -3193,7 +3227,7 @@ mod as_header_name {
31933227
// without breaking any external crate.
31943228
pub trait Sealed {
31953229
#[doc(hidden)]
3196-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName>;
3230+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName>;
31973231

31983232
#[doc(hidden)]
31993233
fn find<T>(&self, map: &HeaderMap<T>) -> Option<(usize, usize)>;
@@ -3207,7 +3241,7 @@ mod as_header_name {
32073241
impl Sealed for HeaderName {
32083242
#[doc(hidden)]
32093243
#[inline]
3210-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3244+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
32113245
Ok(map.entry2(self))
32123246
}
32133247

@@ -3228,7 +3262,7 @@ mod as_header_name {
32283262
impl<'a> Sealed for &'a HeaderName {
32293263
#[doc(hidden)]
32303264
#[inline]
3231-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3265+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
32323266
Ok(map.entry2(self))
32333267
}
32343268

@@ -3249,7 +3283,7 @@ mod as_header_name {
32493283
impl<'a> Sealed for &'a str {
32503284
#[doc(hidden)]
32513285
#[inline]
3252-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3286+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
32533287
HdrName::from_bytes(self.as_bytes(), move |hdr| map.entry2(hdr))
32543288
}
32553289

@@ -3270,8 +3304,8 @@ mod as_header_name {
32703304
impl Sealed for String {
32713305
#[doc(hidden)]
32723306
#[inline]
3273-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3274-
self.as_str().entry(map)
3307+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3308+
self.as_str().try_entry(map)
32753309
}
32763310

32773311
#[doc(hidden)]
@@ -3291,8 +3325,8 @@ mod as_header_name {
32913325
impl<'a> Sealed for &'a String {
32923326
#[doc(hidden)]
32933327
#[inline]
3294-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3295-
self.as_str().entry(map)
3328+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3329+
self.as_str().try_entry(map)
32963330
}
32973331

32983332
#[doc(hidden)]

tests/header_map.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn smoke() {
1111

1212
let name: HeaderName = "hello".parse().unwrap();
1313

14-
match headers.entry(&name).unwrap() {
14+
match headers.entry(&name) {
1515
Entry::Vacant(e) => {
1616
e.insert("world".parse().unwrap());
1717
}
@@ -20,7 +20,7 @@ fn smoke() {
2020

2121
assert!(headers.get("hello").is_some());
2222

23-
match headers.entry(&name).unwrap() {
23+
match headers.entry(&name) {
2424
Entry::Occupied(mut e) => {
2525
assert_eq!(e.get(), &"world");
2626

@@ -98,7 +98,7 @@ fn drain_entry() {
9898

9999
// Using insert
100100
{
101-
let mut e = match headers.entry("hello").unwrap() {
101+
let mut e = match headers.entry("hello") {
102102
Entry::Occupied(e) => e,
103103
_ => panic!(),
104104
};

0 commit comments

Comments
 (0)