Skip to content

Commit e96480d

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 0b21874 commit e96480d

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
@@ -1026,19 +1026,34 @@ impl<T> HeaderMap<T> {
10261026
/// ];
10271027
///
10281028
/// for &header in headers {
1029-
/// let counter = map.entry(header).unwrap().or_insert(0);
1029+
/// let counter = map.entry(header).or_insert(0);
10301030
/// *counter += 1;
10311031
/// }
10321032
///
10331033
/// assert_eq!(map["content-length"], 2);
10341034
/// assert_eq!(map["x-hello"], 1);
10351035
/// ```
1036-
pub fn entry<K>(&mut self, key: K) -> Result<Entry<T>, InvalidHeaderName>
1037-
where K: AsHeaderName,
1036+
pub fn entry<K>(&mut self, key: K) -> Entry<T>
1037+
where K: IntoHeaderName,
10381038
{
10391039
key.entry(self)
10401040
}
10411041

1042+
/// Gets the given key's corresponding entry in the map for in-place
1043+
/// manipulation.
1044+
///
1045+
/// # Errors
1046+
///
1047+
/// This method differs from `entry` by allowing types that may not be
1048+
/// valid `HeaderName`s to passed as the key (such as `String`). If they
1049+
/// do not parse as a valid `HeaderName`, this returns an
1050+
/// `InvalidHeaderName` error.
1051+
pub fn try_entry<K>(&mut self, key: K) -> Result<Entry<T>, InvalidHeaderName>
1052+
where K: AsHeaderName,
1053+
{
1054+
key.try_entry(self)
1055+
}
1056+
10421057
fn entry2<K>(&mut self, key: K) -> Entry<T>
10431058
where K: Hash + Into<HeaderName>,
10441059
HeaderName: PartialEq<K>,
@@ -2237,7 +2252,6 @@ impl<'a, T> Entry<'a, T> {
22372252
///
22382253
/// for &header in headers {
22392254
/// let counter = map.entry(header)
2240-
/// .expect("valid header names")
22412255
/// .or_insert(0);
22422256
/// *counter += 1;
22432257
/// }
@@ -2268,7 +2282,7 @@ impl<'a, T> Entry<'a, T> {
22682282
/// # use http::HeaderMap;
22692283
/// let mut map = HeaderMap::new();
22702284
///
2271-
/// let res = map.entry("x-hello").unwrap()
2285+
/// let res = map.entry("x-hello")
22722286
/// .or_insert_with(|| "world".parse().unwrap());
22732287
///
22742288
/// assert_eq!(res, "world");
@@ -2283,7 +2297,6 @@ impl<'a, T> Entry<'a, T> {
22832297
/// map.insert(HOST, "world".parse().unwrap());
22842298
///
22852299
/// let res = map.entry("host")
2286-
/// .expect("host is a valid string")
22872300
/// .or_insert_with(|| unreachable!());
22882301
///
22892302
///
@@ -2306,7 +2319,7 @@ impl<'a, T> Entry<'a, T> {
23062319
/// # use http::HeaderMap;
23072320
/// let mut map = HeaderMap::new();
23082321
///
2309-
/// assert_eq!(map.entry("x-hello").unwrap().key(), "x-hello");
2322+
/// assert_eq!(map.entry("x-hello").key(), "x-hello");
23102323
/// ```
23112324
pub fn key(&self) -> &HeaderName {
23122325
use self::Entry::*;
@@ -2329,7 +2342,7 @@ impl<'a, T> VacantEntry<'a, T> {
23292342
/// # use http::HeaderMap;
23302343
/// let mut map = HeaderMap::new();
23312344
///
2332-
/// assert_eq!(map.entry("x-hello").unwrap().key().as_str(), "x-hello");
2345+
/// assert_eq!(map.entry("x-hello").key().as_str(), "x-hello");
23332346
/// ```
23342347
pub fn key(&self) -> &HeaderName {
23352348
&self.key
@@ -2343,7 +2356,7 @@ impl<'a, T> VacantEntry<'a, T> {
23432356
/// # use http::header::{HeaderMap, Entry};
23442357
/// let mut map = HeaderMap::new();
23452358
///
2346-
/// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
2359+
/// if let Entry::Vacant(v) = map.entry("x-hello") {
23472360
/// assert_eq!(v.into_key().as_str(), "x-hello");
23482361
/// }
23492362
/// ```
@@ -2362,7 +2375,7 @@ impl<'a, T> VacantEntry<'a, T> {
23622375
/// # use http::header::{HeaderMap, Entry};
23632376
/// let mut map = HeaderMap::new();
23642377
///
2365-
/// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
2378+
/// if let Entry::Vacant(v) = map.entry("x-hello") {
23662379
/// v.insert("world".parse().unwrap());
23672380
/// }
23682381
///
@@ -2391,7 +2404,7 @@ impl<'a, T> VacantEntry<'a, T> {
23912404
/// # use http::header::*;
23922405
/// let mut map = HeaderMap::new();
23932406
///
2394-
/// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
2407+
/// if let Entry::Vacant(v) = map.entry("x-hello") {
23952408
/// let mut e = v.insert_entry("world".parse().unwrap());
23962409
/// e.insert("world2".parse().unwrap());
23972410
/// }
@@ -2709,7 +2722,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27092722
/// let mut map = HeaderMap::new();
27102723
/// map.insert(HOST, "world".parse().unwrap());
27112724
///
2712-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2725+
/// if let Entry::Occupied(e) = map.entry("host") {
27132726
/// assert_eq!("host", e.key());
27142727
/// }
27152728
/// ```
@@ -2732,7 +2745,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27322745
/// let mut map = HeaderMap::new();
27332746
/// map.insert(HOST, "hello.world".parse().unwrap());
27342747
///
2735-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2748+
/// if let Entry::Occupied(mut e) = map.entry("host") {
27362749
/// assert_eq!(e.get(), &"hello.world");
27372750
///
27382751
/// e.append("hello.earth".parse().unwrap());
@@ -2759,7 +2772,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27592772
/// let mut map = HeaderMap::default();
27602773
/// map.insert(HOST, "hello.world".to_string());
27612774
///
2762-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2775+
/// if let Entry::Occupied(mut e) = map.entry("host") {
27632776
/// e.get_mut().push_str("-2");
27642777
/// assert_eq!(e.get(), &"hello.world-2");
27652778
/// }
@@ -2785,7 +2798,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
27852798
/// map.insert(HOST, "hello.world".to_string());
27862799
/// map.append(HOST, "hello.earth".to_string());
27872800
///
2788-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2801+
/// if let Entry::Occupied(e) = map.entry("host") {
27892802
/// e.into_mut().push_str("-2");
27902803
/// }
27912804
///
@@ -2807,7 +2820,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28072820
/// let mut map = HeaderMap::new();
28082821
/// map.insert(HOST, "hello.world".parse().unwrap());
28092822
///
2810-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2823+
/// if let Entry::Occupied(mut e) = map.entry("host") {
28112824
/// let mut prev = e.insert("earth".parse().unwrap());
28122825
/// assert_eq!("hello.world", prev);
28132826
/// }
@@ -2831,7 +2844,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28312844
/// map.insert(HOST, "world".parse().unwrap());
28322845
/// map.append(HOST, "world2".parse().unwrap());
28332846
///
2834-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2847+
/// if let Entry::Occupied(mut e) = map.entry("host") {
28352848
/// let mut prev = e.insert_mult("earth".parse().unwrap());
28362849
/// assert_eq!("world", prev.next().unwrap());
28372850
/// assert_eq!("world2", prev.next().unwrap());
@@ -2856,7 +2869,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28562869
/// let mut map = HeaderMap::new();
28572870
/// map.insert(HOST, "world".parse().unwrap());
28582871
///
2859-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2872+
/// if let Entry::Occupied(mut e) = map.entry("host") {
28602873
/// e.append("earth".parse().unwrap());
28612874
/// }
28622875
///
@@ -2883,7 +2896,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
28832896
/// let mut map = HeaderMap::new();
28842897
/// map.insert(HOST, "world".parse().unwrap());
28852898
///
2886-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2899+
/// if let Entry::Occupied(e) = map.entry("host") {
28872900
/// let mut prev = e.remove();
28882901
/// assert_eq!("world", prev);
28892902
/// }
@@ -2907,7 +2920,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
29072920
/// let mut map = HeaderMap::new();
29082921
/// map.insert(HOST, "world".parse().unwrap());
29092922
///
2910-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2923+
/// if let Entry::Occupied(e) = map.entry("host") {
29112924
/// let (key, mut prev) = e.remove_entry();
29122925
/// assert_eq!("host", key.as_str());
29132926
/// assert_eq!("world", prev);
@@ -2958,7 +2971,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
29582971
/// map.insert(HOST, "world".parse().unwrap());
29592972
/// map.append(HOST, "earth".parse().unwrap());
29602973
///
2961-
/// if let Entry::Occupied(e) = map.entry("host").unwrap() {
2974+
/// if let Entry::Occupied(e) = map.entry("host") {
29622975
/// let mut iter = e.iter();
29632976
/// assert_eq!(&"world", iter.next().unwrap());
29642977
/// assert_eq!(&"earth", iter.next().unwrap());
@@ -2982,7 +2995,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
29822995
/// map.insert(HOST, "world".to_string());
29832996
/// map.append(HOST, "earth".to_string());
29842997
///
2985-
/// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
2998+
/// if let Entry::Occupied(mut e) = map.entry("host") {
29862999
/// for e in e.iter_mut() {
29873000
/// e.push_str("-boop");
29883001
/// }
@@ -3227,7 +3240,7 @@ fn hash_elem_using<K: ?Sized>(danger: &Danger, k: &K) -> HashValue
32273240

32283241

32293242
mod into_header_name {
3230-
use super::{HdrName, HeaderMap, HeaderName};
3243+
use super::{Entry, HdrName, HeaderMap, HeaderName};
32313244

32323245
/// A marker trait used to identify values that can be used as insert keys
32333246
/// to a `HeaderMap`.
@@ -3247,6 +3260,9 @@ mod into_header_name {
32473260

32483261
#[doc(hidden)]
32493262
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool;
3263+
3264+
#[doc(hidden)]
3265+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T>;
32503266
}
32513267

32523268
// ==== impls ====
@@ -3263,6 +3279,12 @@ mod into_header_name {
32633279
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
32643280
map.append2(self, val)
32653281
}
3282+
3283+
#[doc(hidden)]
3284+
#[inline]
3285+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T> {
3286+
map.entry2(self)
3287+
}
32663288
}
32673289

32683290
impl IntoHeaderName for HeaderName {}
@@ -3278,6 +3300,12 @@ mod into_header_name {
32783300
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
32793301
map.append2(self, val)
32803302
}
3303+
3304+
#[doc(hidden)]
3305+
#[inline]
3306+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T> {
3307+
map.entry2(self)
3308+
}
32813309
}
32823310

32833311
impl<'a> IntoHeaderName for &'a HeaderName {}
@@ -3293,6 +3321,12 @@ mod into_header_name {
32933321
fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
32943322
HdrName::from_static(self, move |hdr| map.append2(hdr, val))
32953323
}
3324+
3325+
#[doc(hidden)]
3326+
#[inline]
3327+
fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<T> {
3328+
HdrName::from_static(self, move |hdr| map.entry2(hdr))
3329+
}
32963330
}
32973331

32983332
impl IntoHeaderName for &'static str {}
@@ -3315,7 +3349,7 @@ mod as_header_name {
33153349
// without breaking any external crate.
33163350
pub trait Sealed {
33173351
#[doc(hidden)]
3318-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName>;
3352+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName>;
33193353

33203354
#[doc(hidden)]
33213355
fn find<T>(&self, map: &HeaderMap<T>) -> Option<(usize, usize)>;
@@ -3329,7 +3363,7 @@ mod as_header_name {
33293363
impl Sealed for HeaderName {
33303364
#[doc(hidden)]
33313365
#[inline]
3332-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3366+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
33333367
Ok(map.entry2(self))
33343368
}
33353369

@@ -3350,7 +3384,7 @@ mod as_header_name {
33503384
impl<'a> Sealed for &'a HeaderName {
33513385
#[doc(hidden)]
33523386
#[inline]
3353-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3387+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
33543388
Ok(map.entry2(self))
33553389
}
33563390

@@ -3371,7 +3405,7 @@ mod as_header_name {
33713405
impl<'a> Sealed for &'a str {
33723406
#[doc(hidden)]
33733407
#[inline]
3374-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3408+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
33753409
HdrName::from_bytes(self.as_bytes(), move |hdr| map.entry2(hdr))
33763410
}
33773411

@@ -3392,8 +3426,8 @@ mod as_header_name {
33923426
impl Sealed for String {
33933427
#[doc(hidden)]
33943428
#[inline]
3395-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3396-
self.as_str().entry(map)
3429+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3430+
self.as_str().try_entry(map)
33973431
}
33983432

33993433
#[doc(hidden)]
@@ -3413,8 +3447,8 @@ mod as_header_name {
34133447
impl<'a> Sealed for &'a String {
34143448
#[doc(hidden)]
34153449
#[inline]
3416-
fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3417-
self.as_str().entry(map)
3450+
fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
3451+
self.as_str().try_entry(map)
34183452
}
34193453

34203454
#[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

@@ -148,7 +148,7 @@ fn drain_entry() {
148148

149149
// Using insert
150150
{
151-
let mut e = match headers.entry("hello").unwrap() {
151+
let mut e = match headers.entry("hello") {
152152
Entry::Occupied(e) => e,
153153
_ => panic!(),
154154
};

0 commit comments

Comments
 (0)