diff --git a/src/header/internals/cell.rs b/src/header/internals/cell.rs index fd15b1e9af..dc919e5dce 100644 --- a/src/header/internals/cell.rs +++ b/src/header/internals/cell.rs @@ -86,6 +86,20 @@ impl PtrMapCell { }.map(|val| &mut **val) } + #[inline] + pub fn into_value(self, key: TypeId) -> Option> { + let mut map = unsafe { self.0.into_inner() }; + match map { + PtrMap::Empty => None, + PtrMap::One(id, v) => if id == key { + Some(v) + } else { + None + }, + PtrMap::Many(hm) => hm.remove(&key) + } + } + #[inline] pub unsafe fn insert(&self, key: TypeId, val: Box) { let mut map = &mut *self.0.get(); diff --git a/src/header/internals/item.rs b/src/header/internals/item.rs index bf9ed44638..9f3f8a5f83 100644 --- a/src/header/internals/item.rs +++ b/src/header/internals/item.rs @@ -82,6 +82,14 @@ impl Item { } self.typed.get_mut(tid).map(|typed| unsafe { typed.downcast_mut_unchecked() }) } + + pub fn into_typed(self) -> Option { + let tid = TypeId::of::(); + match self.typed.into_value(tid) { + Some(val) => Some(val), + None => parse::(self.raw.as_ref().expect("item.raw must exist")).ok() + } + } } #[inline] diff --git a/src/header/mod.rs b/src/header/mod.rs index 8e36bf4f97..90c7b07229 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -320,10 +320,11 @@ impl Headers { } /// Removes a header from the map, if one existed. - /// Returns true if a header has been removed. - pub fn remove(&mut self) -> bool { + /// Returns the header, if one has been removed. + pub fn remove(&mut self) -> Option { trace!("Headers.remove( {:?} )", header_name::()); - self.data.remove(&HeaderName(UniCase(Cow::Borrowed(header_name::())))).is_some() + self.data.remove(&HeaderName(UniCase(Cow::Borrowed(header_name::())))) + .and_then(Item::into_typed::) } /// Returns an iterator over the header fields.