From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/http/src/request.rs | 1042 ++++++++++++++++++++++++++++++++++ 1 file changed, 1042 insertions(+) create mode 100644 third_party/rust/http/src/request.rs (limited to 'third_party/rust/http/src/request.rs') diff --git a/third_party/rust/http/src/request.rs b/third_party/rust/http/src/request.rs new file mode 100644 index 0000000000..c249fb96ef --- /dev/null +++ b/third_party/rust/http/src/request.rs @@ -0,0 +1,1042 @@ +//! HTTP request types. +//! +//! This module contains structs related to HTTP requests, notably the +//! `Request` type itself as well as a builder to create requests. Typically +//! you'll import the `http::Request` type rather than reaching into this +//! module itself. +//! +//! # Examples +//! +//! Creating a `Request` to send +//! +//! ```no_run +//! use http::{Request, Response}; +//! +//! let mut request = Request::builder() +//! .uri("https://www.rust-lang.org/") +//! .header("User-Agent", "my-awesome-agent/1.0"); +//! +//! if needs_awesome_header() { +//! request = request.header("Awesome", "yes"); +//! } +//! +//! let response = send(request.body(()).unwrap()); +//! +//! # fn needs_awesome_header() -> bool { +//! # true +//! # } +//! # +//! fn send(req: Request<()>) -> Response<()> { +//! // ... +//! # panic!() +//! } +//! ``` +//! +//! Inspecting a request to see what was sent. +//! +//! ``` +//! use http::{Request, Response, StatusCode}; +//! +//! fn respond_to(req: Request<()>) -> http::Result> { +//! if req.uri() != "/awesome-url" { +//! return Response::builder() +//! .status(StatusCode::NOT_FOUND) +//! .body(()) +//! } +//! +//! let has_awesome_header = req.headers().contains_key("Awesome"); +//! let body = req.body(); +//! +//! // ... +//! # panic!() +//! } +//! ``` + +use std::any::Any; +use std::convert::{TryFrom}; +use std::fmt; + +use crate::header::{HeaderMap, HeaderName, HeaderValue}; +use crate::method::Method; +use crate::version::Version; +use crate::{Extensions, Result, Uri}; + +/// Represents an HTTP request. +/// +/// An HTTP request consists of a head and a potentially optional body. The body +/// component is generic, enabling arbitrary types to represent the HTTP body. +/// For example, the body could be `Vec`, a `Stream` of byte chunks, or a +/// value that has been deserialized. +/// +/// # Examples +/// +/// Creating a `Request` to send +/// +/// ```no_run +/// use http::{Request, Response}; +/// +/// let mut request = Request::builder() +/// .uri("https://www.rust-lang.org/") +/// .header("User-Agent", "my-awesome-agent/1.0"); +/// +/// if needs_awesome_header() { +/// request = request.header("Awesome", "yes"); +/// } +/// +/// let response = send(request.body(()).unwrap()); +/// +/// # fn needs_awesome_header() -> bool { +/// # true +/// # } +/// # +/// fn send(req: Request<()>) -> Response<()> { +/// // ... +/// # panic!() +/// } +/// ``` +/// +/// Inspecting a request to see what was sent. +/// +/// ``` +/// use http::{Request, Response, StatusCode}; +/// +/// fn respond_to(req: Request<()>) -> http::Result> { +/// if req.uri() != "/awesome-url" { +/// return Response::builder() +/// .status(StatusCode::NOT_FOUND) +/// .body(()) +/// } +/// +/// let has_awesome_header = req.headers().contains_key("Awesome"); +/// let body = req.body(); +/// +/// // ... +/// # panic!() +/// } +/// ``` +/// +/// Deserialize a request of bytes via json: +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_json; +/// # extern crate http; +/// use http::Request; +/// use serde::de; +/// +/// fn deserialize(req: Request>) -> serde_json::Result> +/// where for<'de> T: de::Deserialize<'de>, +/// { +/// let (parts, body) = req.into_parts(); +/// let body = serde_json::from_slice(&body)?; +/// Ok(Request::from_parts(parts, body)) +/// } +/// # +/// # fn main() {} +/// ``` +/// +/// Or alternatively, serialize the body of a request to json +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_json; +/// # extern crate http; +/// use http::Request; +/// use serde::ser; +/// +/// fn serialize(req: Request) -> serde_json::Result>> +/// where T: ser::Serialize, +/// { +/// let (parts, body) = req.into_parts(); +/// let body = serde_json::to_vec(&body)?; +/// Ok(Request::from_parts(parts, body)) +/// } +/// # +/// # fn main() {} +/// ``` +pub struct Request { + head: Parts, + body: T, +} + +/// Component parts of an HTTP `Request` +/// +/// The HTTP request head consists of a method, uri, version, and a set of +/// header fields. +pub struct Parts { + /// The request's method + pub method: Method, + + /// The request's URI + pub uri: Uri, + + /// The request's version + pub version: Version, + + /// The request's headers + pub headers: HeaderMap, + + /// The request's extensions + pub extensions: Extensions, + + _priv: (), +} + +/// An HTTP request builder +/// +/// This type can be used to construct an instance or `Request` +/// through a builder-like pattern. +#[derive(Debug)] +pub struct Builder { + inner: Result, +} + +impl Request<()> { + /// Creates a new builder-style object to manufacture a `Request` + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::builder() + /// .method("GET") + /// .uri("https://www.rust-lang.org/") + /// .header("X-Custom-Foo", "Bar") + /// .body(()) + /// .unwrap(); + /// ``` + #[inline] + pub fn builder() -> Builder { + Builder::new() + } + + /// Creates a new `Builder` initialized with a GET method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::get("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn get(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::GET).uri(uri) + } + + /// Creates a new `Builder` initialized with a PUT method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::put("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn put(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::PUT).uri(uri) + } + + /// Creates a new `Builder` initialized with a POST method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::post("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn post(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::POST).uri(uri) + } + + /// Creates a new `Builder` initialized with a DELETE method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::delete("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn delete(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::DELETE).uri(uri) + } + + /// Creates a new `Builder` initialized with an OPTIONS method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::options("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// # assert_eq!(*request.method(), Method::OPTIONS); + /// ``` + pub fn options(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::OPTIONS).uri(uri) + } + + /// Creates a new `Builder` initialized with a HEAD method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::head("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn head(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::HEAD).uri(uri) + } + + /// Creates a new `Builder` initialized with a CONNECT method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::connect("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn connect(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + + { + Builder::new().method(Method::CONNECT).uri(uri) + } + + /// Creates a new `Builder` initialized with a PATCH method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::patch("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn patch(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + { + Builder::new().method(Method::PATCH).uri(uri) + } + + /// Creates a new `Builder` initialized with a TRACE method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::trace("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn trace(uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + { + Builder::new().method(Method::TRACE).uri(uri) + } +} + +impl Request { + /// Creates a new blank `Request` with the body + /// + /// The component parts of this request will be set to their default, e.g. + /// the GET method, no headers, etc. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::new("hello world"); + /// + /// assert_eq!(*request.method(), Method::GET); + /// assert_eq!(*request.body(), "hello world"); + /// ``` + #[inline] + pub fn new(body: T) -> Request { + Request { + head: Parts::new(), + body: body, + } + } + + /// Creates a new `Request` with the given components parts and body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::new("hello world"); + /// let (mut parts, body) = request.into_parts(); + /// parts.method = Method::POST; + /// + /// let request = Request::from_parts(parts, body); + /// ``` + #[inline] + pub fn from_parts(parts: Parts, body: T) -> Request { + Request { + head: parts, + body: body, + } + } + + /// Returns a reference to the associated HTTP method. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert_eq!(*request.method(), Method::GET); + /// ``` + #[inline] + pub fn method(&self) -> &Method { + &self.head.method + } + + /// Returns a mutable reference to the associated HTTP method. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request<()> = Request::default(); + /// *request.method_mut() = Method::PUT; + /// assert_eq!(*request.method(), Method::PUT); + /// ``` + #[inline] + pub fn method_mut(&mut self) -> &mut Method { + &mut self.head.method + } + + /// Returns a reference to the associated URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert_eq!(*request.uri(), *"/"); + /// ``` + #[inline] + pub fn uri(&self) -> &Uri { + &self.head.uri + } + + /// Returns a mutable reference to the associated URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request<()> = Request::default(); + /// *request.uri_mut() = "/hello".parse().unwrap(); + /// assert_eq!(*request.uri(), *"/hello"); + /// ``` + #[inline] + pub fn uri_mut(&mut self) -> &mut Uri { + &mut self.head.uri + } + + /// Returns the associated version. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert_eq!(request.version(), Version::HTTP_11); + /// ``` + #[inline] + pub fn version(&self) -> Version { + self.head.version + } + + /// Returns a mutable reference to the associated version. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request<()> = Request::default(); + /// *request.version_mut() = Version::HTTP_2; + /// assert_eq!(request.version(), Version::HTTP_2); + /// ``` + #[inline] + pub fn version_mut(&mut self) -> &mut Version { + &mut self.head.version + } + + /// Returns a reference to the associated header field map. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert!(request.headers().is_empty()); + /// ``` + #[inline] + pub fn headers(&self) -> &HeaderMap { + &self.head.headers + } + + /// Returns a mutable reference to the associated header field map. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::*; + /// let mut request: Request<()> = Request::default(); + /// request.headers_mut().insert(HOST, HeaderValue::from_static("world")); + /// assert!(!request.headers().is_empty()); + /// ``` + #[inline] + pub fn headers_mut(&mut self) -> &mut HeaderMap { + &mut self.head.headers + } + + /// Returns a reference to the associated extensions. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert!(request.extensions().get::().is_none()); + /// ``` + #[inline] + pub fn extensions(&self) -> &Extensions { + &self.head.extensions + } + + /// Returns a mutable reference to the associated extensions. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::*; + /// let mut request: Request<()> = Request::default(); + /// request.extensions_mut().insert("hello"); + /// assert_eq!(request.extensions().get(), Some(&"hello")); + /// ``` + #[inline] + pub fn extensions_mut(&mut self) -> &mut Extensions { + &mut self.head.extensions + } + + /// Returns a reference to the associated HTTP body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request = Request::default(); + /// assert!(request.body().is_empty()); + /// ``` + #[inline] + pub fn body(&self) -> &T { + &self.body + } + + /// Returns a mutable reference to the associated HTTP body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request = Request::default(); + /// request.body_mut().push_str("hello world"); + /// assert!(!request.body().is_empty()); + /// ``` + #[inline] + pub fn body_mut(&mut self) -> &mut T { + &mut self.body + } + + /// Consumes the request, returning just the body. + /// + /// # Examples + /// + /// ``` + /// # use http::Request; + /// let request = Request::new(10); + /// let body = request.into_body(); + /// assert_eq!(body, 10); + /// ``` + #[inline] + pub fn into_body(self) -> T { + self.body + } + + /// Consumes the request returning the head and body parts. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::new(()); + /// let (parts, body) = request.into_parts(); + /// assert_eq!(parts.method, Method::GET); + /// ``` + #[inline] + pub fn into_parts(self) -> (Parts, T) { + (self.head, self.body) + } + + /// Consumes the request returning a new request with body mapped to the + /// return type of the passed in function. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::builder().body("some string").unwrap(); + /// let mapped_request: Request<&[u8]> = request.map(|b| { + /// assert_eq!(b, "some string"); + /// b.as_bytes() + /// }); + /// assert_eq!(mapped_request.body(), &"some string".as_bytes()); + /// ``` + #[inline] + pub fn map(self, f: F) -> Request + where + F: FnOnce(T) -> U, + { + Request { + body: f(self.body), + head: self.head, + } + } +} + +impl Default for Request { + fn default() -> Request { + Request::new(T::default()) + } +} + +impl fmt::Debug for Request { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Request") + .field("method", self.method()) + .field("uri", self.uri()) + .field("version", &self.version()) + .field("headers", self.headers()) + // omits Extensions because not useful + .field("body", self.body()) + .finish() + } +} + +impl Parts { + /// Creates a new default instance of `Parts` + fn new() -> Parts { + Parts { + method: Method::default(), + uri: Uri::default(), + version: Version::default(), + headers: HeaderMap::default(), + extensions: Extensions::default(), + _priv: (), + } + } +} + +impl fmt::Debug for Parts { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Parts") + .field("method", &self.method) + .field("uri", &self.uri) + .field("version", &self.version) + .field("headers", &self.headers) + // omits Extensions because not useful + // omits _priv because not useful + .finish() + } +} + +impl Builder { + /// Creates a new default instance of `Builder` to construct a `Request`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = request::Builder::new() + /// .method("POST") + /// .body(()) + /// .unwrap(); + /// ``` + #[inline] + pub fn new() -> Builder { + Builder::default() + } + + /// Set the HTTP method for this request. + /// + /// This function will configure the HTTP method of the `Request` that will + /// be returned from `Builder::build`. + /// + /// By default this is `GET`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .method("POST") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn method(self, method: T) -> Builder + where + Method: TryFrom, + >::Error: Into, + { + self.and_then(move |mut head| { + let method = TryFrom::try_from(method).map_err(Into::into)?; + head.method = method; + Ok(head) + }) + } + + /// Get the HTTP Method for this request. + /// + /// By default this is `GET`. If builder has error, returns None. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let mut req = Request::builder(); + /// assert_eq!(req.method_ref(),Some(&Method::GET)); + /// + /// req = req.method("POST"); + /// assert_eq!(req.method_ref(),Some(&Method::POST)); + /// ``` + pub fn method_ref(&self) -> Option<&Method> { + self.inner.as_ref().ok().map(|h| &h.method) + } + + /// Set the URI for this request. + /// + /// This function will configure the URI of the `Request` that will + /// be returned from `Builder::build`. + /// + /// By default this is `/`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .uri("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn uri(self, uri: T) -> Builder + where + Uri: TryFrom, + >::Error: Into, + { + self.and_then(move |mut head| { + head.uri = TryFrom::try_from(uri).map_err(Into::into)?; + Ok(head) + }) + } + + /// Get the URI for this request + /// + /// By default this is `/`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let mut req = Request::builder(); + /// assert_eq!(req.uri_ref().unwrap(), "/" ); + /// + /// req = req.uri("https://www.rust-lang.org/"); + /// assert_eq!(req.uri_ref().unwrap(), "https://www.rust-lang.org/" ); + /// ``` + pub fn uri_ref(&self) -> Option<&Uri> { + self.inner.as_ref().ok().map(|h| &h.uri) + } + + /// Set the HTTP version for this request. + /// + /// This function will configure the HTTP version of the `Request` that + /// will be returned from `Builder::build`. + /// + /// By default this is HTTP/1.1 + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .version(Version::HTTP_2) + /// .body(()) + /// .unwrap(); + /// ``` + pub fn version(self, version: Version) -> Builder { + self.and_then(move |mut head| { + head.version = version; + Ok(head) + }) + } + + /// Appends a header to this request builder. + /// + /// This function will append the provided key/value as a header to the + /// internal `HeaderMap` being constructed. Essentially this is equivalent + /// to calling `HeaderMap::append`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// + /// let req = Request::builder() + /// .header("Accept", "text/html") + /// .header("X-Custom-Foo", "bar") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn header(self, key: K, value: V) -> Builder + where + HeaderName: TryFrom, + >::Error: Into, + HeaderValue: TryFrom, + >::Error: Into, + { + self.and_then(move |mut head| { + let name = >::try_from(key).map_err(Into::into)?; + let value = >::try_from(value).map_err(Into::into)?; + head.headers.append(name, value); + Ok(head) + }) + } + + /// Get header on this request builder. + /// when builder has error returns None + /// + /// # Example + /// + /// ``` + /// # use http::Request; + /// let req = Request::builder() + /// .header("Accept", "text/html") + /// .header("X-Custom-Foo", "bar"); + /// let headers = req.headers_ref().unwrap(); + /// assert_eq!( headers["Accept"], "text/html" ); + /// assert_eq!( headers["X-Custom-Foo"], "bar" ); + /// ``` + pub fn headers_ref(&self) -> Option<&HeaderMap> { + self.inner.as_ref().ok().map(|h| &h.headers) + } + + /// Get headers on this request builder. + /// + /// When builder has error returns None. + /// + /// # Example + /// + /// ``` + /// # use http::{header::HeaderValue, Request}; + /// let mut req = Request::builder(); + /// { + /// let headers = req.headers_mut().unwrap(); + /// headers.insert("Accept", HeaderValue::from_static("text/html")); + /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar")); + /// } + /// let headers = req.headers_ref().unwrap(); + /// assert_eq!( headers["Accept"], "text/html" ); + /// assert_eq!( headers["X-Custom-Foo"], "bar" ); + /// ``` + pub fn headers_mut(&mut self) -> Option<&mut HeaderMap> { + self.inner.as_mut().ok().map(|h| &mut h.headers) + } + + /// Adds an extension to this builder + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .extension("My Extension") + /// .body(()) + /// .unwrap(); + /// + /// assert_eq!(req.extensions().get::<&'static str>(), + /// Some(&"My Extension")); + /// ``` + pub fn extension(self, extension: T) -> Builder + where + T: Any + Send + Sync + 'static, + { + self.and_then(move |mut head| { + head.extensions.insert(extension); + Ok(head) + }) + } + + /// "Consumes" this builder, using the provided `body` to return a + /// constructed `Request`. + /// + /// # Errors + /// + /// This function may return an error if any previously configured argument + /// failed to parse or get converted to the internal representation. For + /// example if an invalid `head` was specified via `header("Foo", + /// "Bar\r\n")` the error will be returned when this function is called + /// rather than when `header` was called. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::builder() + /// .body(()) + /// .unwrap(); + /// ``` + pub fn body(self, body: T) -> Result> { + self.inner.map(move |head| { + Request { + head, + body, + } + }) + } + + // private + + fn and_then(self, func: F) -> Self + where + F: FnOnce(Parts) -> Result + { + Builder { + inner: self.inner.and_then(func), + } + } +} + +impl Default for Builder { + #[inline] + fn default() -> Builder { + Builder { + inner: Ok(Parts::new()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_can_map_a_body_from_one_type_to_another() { + let request = Request::builder().body("some string").unwrap(); + let mapped_request = request.map(|s| { + assert_eq!(s, "some string"); + 123u32 + }); + assert_eq!(mapped_request.body(), &123u32); + } +} -- cgit v1.2.3