1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-02-25 05:12:49 +01:00

expose header::map module (#2470)

This commit is contained in:
Rob Ede 2021-11-29 02:22:47 +00:00 committed by GitHub
parent 654dc64a09
commit fc4cdf81eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 79 additions and 24 deletions

View File

@ -3,9 +3,11 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
### Changed ### Changed
* Guarantee ordering of `header::GetAll` iterator to be same as insertion order. [#2467] * Guarantee ordering of `header::GetAll` iterator to be same as insertion order. [#2467]
* Expose `header::{GetAll, Removed}` iterators. [#2467] * Expose `header::map` module. [#2467]
* Implement `ExactSizeIterator` and `FusedIterator` for all `HeaderMap` iterators. [#2470]
[#2467]: https://github.com/actix/actix-web/pull/2467 [#2467]: https://github.com/actix/actix-web/pull/2467
[#2470]: https://github.com/actix/actix-web/pull/2470
## 3.0.0-beta.13 - 2021-11-22 ## 3.0.0-beta.13 - 2021-11-22

View File

@ -1,11 +1,12 @@
//! Helper trait for types that can be effectively borrowed as a [HeaderValue]. //! Sealed [`AsHeaderName`] trait and implementations.
//!
//! [HeaderValue]: crate::http::HeaderValue
use std::{borrow::Cow, str::FromStr}; use std::{borrow::Cow, str::FromStr as _};
use http::header::{HeaderName, InvalidHeaderName}; use http::header::{HeaderName, InvalidHeaderName};
/// Sealed trait implemented for types that can be effectively borrowed as a [`HeaderValue`].
///
/// [`HeaderValue`]: crate::http::HeaderValue
pub trait AsHeaderName: Sealed {} pub trait AsHeaderName: Sealed {}
pub struct Seal; pub struct Seal;

View File

@ -1,4 +1,6 @@
use std::convert::TryFrom; //! [`IntoHeaderPair`] trait and implementations.
use std::convert::TryFrom as _;
use http::{ use http::{
header::{HeaderName, InvalidHeaderName, InvalidHeaderValue}, header::{HeaderName, InvalidHeaderName, InvalidHeaderValue},
@ -7,7 +9,10 @@ use http::{
use super::{Header, IntoHeaderValue}; use super::{Header, IntoHeaderValue};
/// Transforms structures into header K/V pairs for inserting into `HeaderMap`s. /// An interface for types that can be converted into a [`HeaderName`]/[`HeaderValue`] pair for
/// insertion into a [`HeaderMap`].
///
/// [`HeaderMap`]: crate::http::HeaderMap
pub trait IntoHeaderPair: Sized { pub trait IntoHeaderPair: Sized {
type Error: Into<HttpError>; type Error: Into<HttpError>;

View File

@ -1,10 +1,12 @@
use std::convert::TryFrom; //! [`IntoHeaderValue`] trait and implementations.
use std::convert::TryFrom as _;
use bytes::Bytes; use bytes::Bytes;
use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue}; use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue};
use mime::Mime; use mime::Mime;
/// A trait for any object that can be Converted to a `HeaderValue` /// An interface for types that can be converted into a [`HeaderValue`].
pub trait IntoHeaderValue: Sized { pub trait IntoHeaderValue: Sized {
/// The type returned in the event of a conversion error. /// The type returned in the event of a conversion error.
type Error: Into<HttpError>; type Error: Into<HttpError>;

View File

@ -1,6 +1,6 @@
//! A multi-value [`HeaderMap`] and its iterators. //! A multi-value [`HeaderMap`] and its iterators.
use std::{borrow::Cow, collections::hash_map, ops}; use std::{borrow::Cow, collections::hash_map, iter, ops};
use ahash::AHashMap; use ahash::AHashMap;
use http::header::{HeaderName, HeaderValue}; use http::header::{HeaderName, HeaderValue};
@ -581,7 +581,8 @@ impl HeaderMap {
} }
} }
/// Note that this implementation will clone a [HeaderName] for each value. /// Note that this implementation will clone a [HeaderName] for each value. Consider using
/// [`drain`](Self::drain) to control header name cloning.
impl IntoIterator for HeaderMap { impl IntoIterator for HeaderMap {
type Item = (HeaderName, HeaderValue); type Item = (HeaderName, HeaderValue);
type IntoIter = IntoIter; type IntoIter = IntoIter;
@ -602,7 +603,7 @@ impl<'a> IntoIterator for &'a HeaderMap {
} }
} }
/// Iterator for references of [`HeaderValue`]s with the same associated [`HeaderName`]. /// Iterator over borrowed values with the same associated name.
/// ///
/// See [`HeaderMap::get_all`]. /// See [`HeaderMap::get_all`].
#[derive(Debug)] #[derive(Debug)]
@ -644,10 +645,14 @@ impl<'a> Iterator for GetAll<'a> {
} }
} }
/// Iterator for owned [`HeaderValue`]s with the same associated [`HeaderName`] returned from impl ExactSizeIterator for GetAll<'_> {}
/// methods that remove or replace items.
impl iter::FusedIterator for GetAll<'_> {}
/// Iterator over removed, owned values with the same associated name.
/// ///
/// See [`HeaderMap::insert`] and [`HeaderMap::remove`]. /// Returned from methods that remove or replace items. See [`HeaderMap::insert`]
/// and [`HeaderMap::remove`].
#[derive(Debug)] #[derive(Debug)]
pub struct Removed { pub struct Removed {
inner: Option<smallvec::IntoIter<[HeaderValue; 4]>>, inner: Option<smallvec::IntoIter<[HeaderValue; 4]>>,
@ -689,7 +694,11 @@ impl Iterator for Removed {
} }
} }
/// Iterator over all [`HeaderName`]s in the map. impl ExactSizeIterator for Removed {}
impl iter::FusedIterator for Removed {}
/// Iterator over all names in the map.
#[derive(Debug)] #[derive(Debug)]
pub struct Keys<'a>(hash_map::Keys<'a, HeaderName, Value>); pub struct Keys<'a>(hash_map::Keys<'a, HeaderName, Value>);
@ -707,6 +716,11 @@ impl<'a> Iterator for Keys<'a> {
} }
} }
impl ExactSizeIterator for Keys<'_> {}
impl iter::FusedIterator for Keys<'_> {}
/// Iterator over borrowed name-value pairs.
#[derive(Debug)] #[derive(Debug)]
pub struct Iter<'a> { pub struct Iter<'a> {
inner: hash_map::Iter<'a, HeaderName, Value>, inner: hash_map::Iter<'a, HeaderName, Value>,
@ -758,6 +772,10 @@ impl<'a> Iterator for Iter<'a> {
} }
} }
impl ExactSizeIterator for Iter<'_> {}
impl iter::FusedIterator for Iter<'_> {}
/// Iterator over drained name-value pairs. /// Iterator over drained name-value pairs.
/// ///
/// Iterator items are `(Option<HeaderName>, HeaderValue)` to avoid cloning. /// Iterator items are `(Option<HeaderName>, HeaderValue)` to avoid cloning.
@ -809,6 +827,10 @@ impl<'a> Iterator for Drain<'a> {
} }
} }
impl ExactSizeIterator for Drain<'_> {}
impl iter::FusedIterator for Drain<'_> {}
/// Iterator over owned name-value pairs. /// Iterator over owned name-value pairs.
/// ///
/// Implementation necessarily clones header names for each value. /// Implementation necessarily clones header names for each value.
@ -859,12 +881,27 @@ impl Iterator for IntoIter {
} }
} }
impl ExactSizeIterator for IntoIter {}
impl iter::FusedIterator for IntoIter {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::iter::FusedIterator;
use http::header; use http::header;
use static_assertions::assert_impl_all;
use super::*; use super::*;
assert_impl_all!(HeaderMap: IntoIterator);
assert_impl_all!(Keys<'_>: Iterator, ExactSizeIterator, FusedIterator);
assert_impl_all!(GetAll<'_>: Iterator, ExactSizeIterator, FusedIterator);
assert_impl_all!(Removed: Iterator, ExactSizeIterator, FusedIterator);
assert_impl_all!(Iter<'_>: Iterator, ExactSizeIterator, FusedIterator);
assert_impl_all!(IntoIter: Iterator, ExactSizeIterator, FusedIterator);
assert_impl_all!(Drain<'_>: Iterator, ExactSizeIterator, FusedIterator);
#[test] #[test]
fn create() { fn create() {
let map = HeaderMap::new(); let map = HeaderMap::new();
@ -1035,6 +1072,9 @@ mod tests {
assert_eq!(vals.next().unwrap().as_bytes(), b"8"); assert_eq!(vals.next().unwrap().as_bytes(), b"8");
assert_eq!(vals.next().unwrap().as_bytes(), b"9"); assert_eq!(vals.next().unwrap().as_bytes(), b"9");
assert!(vals.next().is_none()); assert!(vals.next().is_none());
// check for fused-ness
assert!(vals.next().is_none());
} }
fn owned_pair<'a>( fn owned_pair<'a>(

View File

@ -34,7 +34,7 @@ use crate::{error::ParseError, HttpMessage};
mod as_name; mod as_name;
mod into_pair; mod into_pair;
mod into_value; mod into_value;
pub(crate) mod map; pub mod map;
mod shared; mod shared;
mod utils; mod utils;
@ -44,12 +44,12 @@ pub use self::shared::*;
pub use self::as_name::AsHeaderName; pub use self::as_name::AsHeaderName;
pub use self::into_pair::IntoHeaderPair; pub use self::into_pair::IntoHeaderPair;
pub use self::into_value::IntoHeaderValue; pub use self::into_value::IntoHeaderValue;
pub use self::map::{GetAll, HeaderMap, Removed}; pub use self::map::HeaderMap;
pub use self::utils::{ pub use self::utils::{
fmt_comma_delimited, from_comma_delimited, from_one_raw_str, http_percent_encode, fmt_comma_delimited, from_comma_delimited, from_one_raw_str, http_percent_encode,
}; };
/// A trait for any object that already represents a valid header field and value. /// An interface for types that already represent a valid header.
pub trait Header: IntoHeaderValue { pub trait Header: IntoHeaderValue {
/// Returns the name of the header field /// Returns the name of the header field
fn name() -> HeaderName; fn name() -> HeaderName;

View File

@ -9,14 +9,17 @@ use crate::{
HttpMessage, HttpMessage,
}; };
/// Error return when a content encoding is unknown. /// Error returned when a content encoding is unknown.
///
/// Example: 'compress'
#[derive(Debug, Display, Error)] #[derive(Debug, Display, Error)]
#[display(fmt = "unsupported content encoding")] #[display(fmt = "unsupported content encoding")]
pub struct ContentEncodingParseError; pub struct ContentEncodingParseError;
/// Represents a supported content encoding. /// Represents a supported content encoding.
///
/// Includes a commonly-used subset of media types appropriate for use as HTTP content encodings.
/// See [IANA HTTP Content Coding Registry].
///
/// [IANA HTTP Content Coding Registry]: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive] #[non_exhaustive]
pub enum ContentEncoding { pub enum ContentEncoding {
@ -32,7 +35,7 @@ pub enum ContentEncoding {
/// Gzip algorithm. /// Gzip algorithm.
Gzip, Gzip,
// Zstd algorithm. /// Zstd algorithm.
Zstd, Zstd,
/// Indicates the identity function (i.e. no compression, nor modification). /// Indicates the identity function (i.e. no compression, nor modification).

View File

@ -1,3 +1,5 @@
//! Header parsing utilities.
use std::{fmt, str::FromStr}; use std::{fmt, str::FromStr};
use super::HeaderValue; use super::HeaderValue;

View File

@ -296,7 +296,7 @@ impl Future for HttpResponse<AnyBody> {
#[cfg(feature = "cookies")] #[cfg(feature = "cookies")]
pub struct CookieIter<'a> { pub struct CookieIter<'a> {
iter: header::GetAll<'a>, iter: header::map::GetAll<'a>,
} }
#[cfg(feature = "cookies")] #[cfg(feature = "cookies")]