feat(headers): Headers::remove returns the Header
Closes #891 BREAKING CHANGE: `Headers.remove()` used to return a `bool`, it now returns `Option<H>`. To determine if a a header exists, switch to `Headers.has()`.
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							74136de960
						
					
				
				
					commit
					9375addba0
				
			| @@ -86,6 +86,20 @@ impl<V: ?Sized + Any + 'static> PtrMapCell<V> { | |||||||
|         }.map(|val| &mut **val) |         }.map(|val| &mut **val) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[inline] | ||||||
|  |     pub fn into_value(self, key: TypeId) -> Option<Box<V>> { | ||||||
|  |         let map = unsafe { self.0.into_inner() }; | ||||||
|  |         match map { | ||||||
|  |             PtrMap::Empty => None, | ||||||
|  |             PtrMap::One(id, v) => if id == key { | ||||||
|  |                 Some(v) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             }, | ||||||
|  |             PtrMap::Many(mut hm) => hm.remove(&key) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub unsafe fn insert(&self, key: TypeId, val: Box<V>) { |     pub unsafe fn insert(&self, key: TypeId, val: Box<V>) { | ||||||
|         let mut map = &mut *self.0.get(); |         let mut map = &mut *self.0.get(); | ||||||
|   | |||||||
| @@ -82,6 +82,14 @@ impl Item { | |||||||
|         } |         } | ||||||
|         self.typed.get_mut(tid).map(|typed| unsafe { typed.downcast_mut_unchecked() }) |         self.typed.get_mut(tid).map(|typed| unsafe { typed.downcast_mut_unchecked() }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn into_typed<H: Header>(self) -> Option<H> { | ||||||
|  |         let tid = TypeId::of::<H>(); | ||||||
|  |         match self.typed.into_value(tid) { | ||||||
|  |             Some(val) => Some(val), | ||||||
|  |             None => parse::<H>(self.raw.as_ref().expect("item.raw must exist")).ok() | ||||||
|  |         }.map(|typed| unsafe { typed.downcast_unchecked() }) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[inline] | #[inline] | ||||||
|   | |||||||
| @@ -182,6 +182,11 @@ impl Header + Send + Sync { | |||||||
|     unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { |     unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { | ||||||
|         &mut *(mem::transmute::<*mut _, (*mut (), *mut ())>(self).0 as *mut T) |         &mut *(mem::transmute::<*mut _, (*mut (), *mut ())>(self).0 as *mut T) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[inline] | ||||||
|  |     unsafe fn downcast_unchecked<T: 'static>(self: Box<Self>) -> T { | ||||||
|  |         *Box::from_raw(mem::transmute::<*mut _, (*mut (), *mut ())>(Box::into_raw(self)).0 as *mut T) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Clone for Box<Header + Send + Sync> { | impl Clone for Box<Header + Send + Sync> { | ||||||
| @@ -320,10 +325,14 @@ impl Headers { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Removes a header from the map, if one existed. |     /// Removes a header from the map, if one existed. | ||||||
|     /// Returns true if a header has been removed. |     /// Returns the header, if one has been removed and could be parsed. | ||||||
|     pub fn remove<H: Header>(&mut self) -> bool { |     /// | ||||||
|  |     /// Note that this function may return `None` even though a header was removed. If you want to | ||||||
|  |     /// know whether a header exists, rather rely on `has`. | ||||||
|  |     pub fn remove<H: Header>(&mut self) -> Option<H> { | ||||||
|         trace!("Headers.remove( {:?} )", header_name::<H>()); |         trace!("Headers.remove( {:?} )", header_name::<H>()); | ||||||
|         self.data.remove(&HeaderName(UniCase(Cow::Borrowed(header_name::<H>())))).is_some() |         self.data.remove(&HeaderName(UniCase(Cow::Borrowed(header_name::<H>())))) | ||||||
|  |             .and_then(Item::into_typed::<H>) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Returns an iterator over the header fields. |     /// Returns an iterator over the header fields. | ||||||
| @@ -751,6 +760,13 @@ mod tests { | |||||||
|         assert_eq!(headers.get_raw("Content-length"), None); |         assert_eq!(headers.get_raw("Content-length"), None); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_remove() { | ||||||
|  |         let mut headers = Headers::new(); | ||||||
|  |         headers.set(ContentLength(10)); | ||||||
|  |         assert_eq!(headers.remove(), Some(ContentLength(10))); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_len() { |     fn test_len() { | ||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user