Skip to main content

rama_http_types/
response.rs

1use std::borrow::Cow;
2use std::convert::TryInto;
3use std::fmt::{self, Display};
4
5use crate::header::{HeaderMap, HeaderName, HeaderValue};
6use crate::proto::h1::ext::ReasonPhrase;
7use crate::status::StatusCode;
8use crate::version::Version;
9use crate::{Body, Result};
10use rama_core::extensions::{Extension, Extensions, ExtensionsRef};
11use rama_utils::macros::generate_set_and_with;
12
13/// Represents an HTTP response
14///
15/// An HTTP response consists of a head and a potentially optional body. The body
16/// component is generic, enabling arbitrary types to represent the HTTP body.
17/// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a
18/// value that has been deserialized.
19///
20/// The Serde representation contains `status`, `version`, `headers`, and
21/// `body`. Typed [`Extensions`] are process-local values and are intentionally
22/// omitted. Deserializing therefore creates empty extensions.
23///
24/// Typically you'll work with responses on the client side as the result of
25/// sending a `Request` and on the server you'll be generating a `Response` to
26/// send back to the client.
27///
28/// # Examples
29///
30/// Creating a `Response` to return
31///
32/// ```
33/// use rama_http_types::{Request, Response, StatusCode};
34///
35/// fn respond_to(req: Request<()>) -> rama_http_types::Result<Response<()>> {
36///     let mut builder = Response::builder()
37///         .header("Foo", "Bar")
38///         .status(StatusCode::OK);
39///
40///     if req.headers().contains_key("Another-Header") {
41///         builder = builder.header("Another-Header", "Ack");
42///     }
43///
44///     builder.body(())
45/// }
46/// ```
47///
48/// A simple 404 handler
49///
50/// ```
51/// use rama_http_types::{Request, Response, StatusCode};
52///
53/// fn not_found(_req: Request<()>) -> rama_http_types::Result<Response<()>> {
54///     Response::builder()
55///         .status(StatusCode::NOT_FOUND)
56///         .body(())
57/// }
58/// ```
59///
60/// Or otherwise inspecting the result of a request:
61///
62/// ```no_run
63/// use rama_http_types::{Request, Response};
64///
65/// fn get(url: &str) -> rama_http_types::Result<Response<()>> {
66///     // ...
67/// # panic!()
68/// }
69///
70/// let response = get("https://www.rust-lang.org/").unwrap();
71///
72/// if !response.status().is_success() {
73///     panic!("failed to get a successful response status!");
74/// }
75///
76/// if let Some(date) = response.headers().get("Date") {
77///     // we've got a `Date` header!
78/// }
79///
80/// let body = response.body();
81/// // ...
82/// ```
83///
84/// Deserialize a response of bytes via json:
85///
86/// ```
87/// use rama_http_types::Response;
88/// use serde::de;
89///
90/// fn deserialize<T>(res: Response<Vec<u8>>) -> serde_json::Result<Response<T>>
91///     where for<'de> T: de::Deserialize<'de>,
92/// {
93///     let (parts, body) = res.into_parts();
94///     let body = serde_json::from_slice(&body)?;
95///     Ok(Response::from_parts(parts, body))
96/// }
97/// #
98/// # fn main() {}
99/// ```
100///
101/// Or alternatively, serialize the body of a response to json
102///
103/// ```
104/// use rama_http_types::Response;
105/// use serde::ser;
106///
107/// fn serialize<T>(res: Response<T>) -> serde_json::Result<Response<Vec<u8>>>
108///     where T: ser::Serialize,
109/// {
110///     let (parts, body) = res.into_parts();
111///     let body = serde_json::to_vec(&body)?;
112///     Ok(Response::from_parts(parts, body))
113/// }
114/// #
115/// # fn main() {}
116/// ```
117#[derive(Clone)]
118pub struct Response<T = Body> {
119    head: Parts,
120    body: T,
121}
122
123/// Component parts of an HTTP `Response`
124///
125/// The HTTP response head consists of a status, version, and a set of
126/// header fields.
127#[non_exhaustive]
128#[derive(Clone)]
129pub struct Parts {
130    /// The response's status
131    pub status: StatusCode,
132
133    /// The response's version
134    pub version: Version,
135
136    /// The response's headers
137    pub headers: HeaderMap<HeaderValue>,
138
139    /// The response's extensions
140    pub extensions: Extensions,
141}
142
143#[derive(serde::Deserialize)]
144#[serde(rename = "ResponseParts")]
145struct ResponsePartsSerde {
146    status: StatusCode,
147    version: Version,
148    headers: HeaderMap<HeaderValue>,
149}
150
151impl serde::Serialize for Parts {
152    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
153    where
154        S: serde::Serializer,
155    {
156        use serde::ser::SerializeStruct as _;
157
158        let mut state = serializer.serialize_struct("ResponseParts", 3)?;
159        state.serialize_field("status", &self.status)?;
160        state.serialize_field("version", &self.version)?;
161        state.serialize_field("headers", &self.headers)?;
162        state.end()
163    }
164}
165
166impl<'de> serde::Deserialize<'de> for Parts {
167    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
168    where
169        D: serde::Deserializer<'de>,
170    {
171        let repr = ResponsePartsSerde::deserialize(deserializer)?;
172        Ok(Self {
173            status: repr.status,
174            version: repr.version,
175            headers: repr.headers,
176            extensions: Extensions::new(),
177        })
178    }
179}
180
181impl<T: serde::Serialize> serde::Serialize for Response<T> {
182    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
183    where
184        S: serde::Serializer,
185    {
186        use serde::ser::SerializeStruct as _;
187
188        let mut state = serializer.serialize_struct("Response", 4)?;
189        state.serialize_field("status", &self.head.status)?;
190        state.serialize_field("version", &self.head.version)?;
191        state.serialize_field("headers", &self.head.headers)?;
192        state.serialize_field("body", &self.body)?;
193        state.end()
194    }
195}
196
197#[derive(serde::Deserialize)]
198#[serde(rename = "Response")]
199struct ResponseSerde<T> {
200    status: StatusCode,
201    version: Version,
202    headers: HeaderMap<HeaderValue>,
203    body: T,
204}
205
206impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Response<T> {
207    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
208    where
209        D: serde::Deserializer<'de>,
210    {
211        let repr = ResponseSerde::deserialize(deserializer)?;
212        Ok(Self {
213            head: Parts {
214                status: repr.status,
215                version: repr.version,
216                headers: repr.headers,
217                extensions: Extensions::new(),
218            },
219            body: repr.body,
220        })
221    }
222}
223
224impl ExtensionsRef for Parts {
225    fn extensions(&self) -> &Extensions {
226        &self.extensions
227    }
228}
229
230/// An HTTP response builder
231///
232/// This type can be used to construct an instance of `Response` through a
233/// builder-like pattern.
234#[derive(Debug)]
235#[must_use]
236pub struct Builder {
237    inner: Result<Parts>,
238}
239
240impl Response<()> {
241    /// Creates a new builder-style object to manufacture a `Response`
242    ///
243    /// This method returns an instance of `Builder` which can be used to
244    /// create a `Response`.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// # use rama_http_types::*;
250    /// let response = Response::builder()
251    ///     .status(200)
252    ///     .header("X-Custom-Foo", "Bar")
253    ///     .body(())
254    ///     .unwrap();
255    /// ```
256    #[inline]
257    pub fn builder() -> Builder {
258        Builder::new()
259    }
260
261    #[inline]
262    /// Same as [`Response::builder`] but with the given [`Extensions`] to start from.
263    pub fn builder_with_extensions(ext: Extensions) -> Builder {
264        Builder::new_with_extensions(ext)
265    }
266}
267
268impl<T> Response<T> {
269    /// Creates a new blank `Response` with the body
270    ///
271    /// The component parts of this response will be set to their default, e.g.
272    /// the ok status, no headers, etc.
273    ///
274    /// # Examples
275    ///
276    /// ```
277    /// # use rama_http_types::*;
278    /// let response = Response::new("hello world");
279    ///
280    /// assert_eq!(response.status(), StatusCode::OK);
281    /// assert_eq!(*response.body(), "hello world");
282    /// ```
283    #[inline]
284    pub fn new(body: T) -> Self {
285        Self {
286            head: Parts::new(),
287            body,
288        }
289    }
290
291    /// Creates a new `Response` with the given head and body
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// # use rama_http_types::*;
297    /// let response = Response::new("hello world");
298    /// let (mut parts, body) = response.into_parts();
299    ///
300    /// parts.status = StatusCode::BAD_REQUEST;
301    /// let response = Response::from_parts(parts, body);
302    ///
303    /// assert_eq!(response.status(), StatusCode::BAD_REQUEST);
304    /// assert_eq!(*response.body(), "hello world");
305    /// ```
306    #[inline]
307    pub fn from_parts(parts: Parts, body: T) -> Self {
308        Self { head: parts, body }
309    }
310
311    /// Returns the `StatusCode`.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// # use rama_http_types::*;
317    /// let response: Response<()> = Response::default();
318    /// assert_eq!(response.status(), StatusCode::OK);
319    /// ```
320    #[inline]
321    pub fn status(&self) -> StatusCode {
322        self.head.status
323    }
324
325    /// Returns a mutable reference to the associated `StatusCode`.
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// # use rama_http_types::*;
331    /// let mut response: Response<()> = Response::default();
332    /// *response.status_mut() = StatusCode::CREATED;
333    /// assert_eq!(response.status(), StatusCode::CREATED);
334    /// ```
335    #[inline]
336    pub fn status_mut(&mut self) -> &mut StatusCode {
337        &mut self.head.status
338    }
339
340    /// Turn a response into an error if the server returned an error.
341    ///
342    /// # Example
343    ///
344    /// ```
345    /// # use rama_http_types::Response;
346    /// fn on_response(res: Response) {
347    ///     match res.error_for_status() {
348    ///         Ok(_res) => (),
349    ///         Err(err) => {
350    ///             // asserting a 400 as an example
351    ///             // it could be any status between 400...599
352    ///             assert_eq!(
353    ///                 err.status(),
354    ///                 rama_http_types::StatusCode::BAD_REQUEST,
355    ///             );
356    ///         }
357    ///     }
358    /// }
359    /// # fn main() {}
360    /// ```
361    pub fn error_for_status(self) -> std::result::Result<Self, StatusCodeError> {
362        let status = self.status();
363
364        if status.is_client_error() || status.is_server_error() {
365            Err(StatusCodeError {
366                status,
367                reason: match self.extensions().get_ref::<ReasonPhrase>() {
368                    Some(reason) => Some(
369                        String::from_utf8_lossy(reason.as_bytes())
370                            .into_owned()
371                            .into(),
372                    ),
373                    None => status.canonical_reason().map(Into::into),
374                },
375            })
376        } else {
377            Ok(self)
378        }
379    }
380
381    /// Turn a reference to a response into an error if the server returned an error.
382    ///
383    /// # Example
384    ///
385    /// ```
386    /// # use rama_http_types::Response;
387    /// fn on_response(res: &Response) {
388    ///     match res.error_for_status_ref() {
389    ///         Ok(_res) => (),
390    ///         Err(err) => {
391    ///             // asserting a 400 as an example
392    ///             // it could be any status between 400...599
393    ///             assert_eq!(
394    ///                 err.status(),
395    ///                 rama_http_types::StatusCode::BAD_REQUEST
396    ///             );
397    ///         }
398    ///     }
399    /// }
400    /// # fn main() {}
401    /// ```
402    pub fn error_for_status_ref(&self) -> std::result::Result<&Self, StatusCodeError> {
403        let status = self.status();
404
405        if status.is_client_error() || status.is_server_error() {
406            Err(StatusCodeError {
407                status,
408                reason: match self.extensions().get_ref::<ReasonPhrase>() {
409                    Some(reason) => Some(
410                        String::from_utf8_lossy(reason.as_bytes())
411                            .into_owned()
412                            .into(),
413                    ),
414                    None => status.canonical_reason().map(Into::into),
415                },
416            })
417        } else {
418            Ok(self)
419        }
420    }
421
422    /// Returns a reference to the associated version.
423    ///
424    /// # Examples
425    ///
426    /// ```
427    /// # use rama_http_types::*;
428    /// let response: Response<()> = Response::default();
429    /// assert_eq!(response.version(), Version::HTTP_11);
430    /// ```
431    #[inline]
432    pub fn version(&self) -> Version {
433        self.head.version
434    }
435
436    /// Returns a mutable reference to the associated version.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// # use rama_http_types::*;
442    /// let mut response: Response<()> = Response::default();
443    /// *response.version_mut() = Version::HTTP_2;
444    /// assert_eq!(response.version(), Version::HTTP_2);
445    /// ```
446    #[inline]
447    pub fn version_mut(&mut self) -> &mut Version {
448        &mut self.head.version
449    }
450
451    /// Returns a reference to the associated header field map.
452    ///
453    /// # Examples
454    ///
455    /// ```
456    /// # use rama_http_types::*;
457    /// let response: Response<()> = Response::default();
458    /// assert!(response.headers().is_empty());
459    /// ```
460    #[inline]
461    pub fn headers(&self) -> &HeaderMap<HeaderValue> {
462        &self.head.headers
463    }
464
465    /// Returns a mutable reference to the associated header field map.
466    ///
467    /// # Examples
468    ///
469    /// ```
470    /// # use rama_http_types::*;
471    /// # use rama_http_types::header::*;
472    /// let mut response: Response<()> = Response::default();
473    /// response.headers_mut().insert(HOST, HeaderValue::from_static("world"));
474    /// assert!(!response.headers().is_empty());
475    /// ```
476    #[inline]
477    pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
478        &mut self.head.headers
479    }
480
481    /// Returned a cloned of the associated HTTP header.
482    #[inline]
483    pub fn clone_parts(&self) -> Parts {
484        self.head.clone()
485    }
486
487    /// Returns a reference to the associated HTTP body.
488    ///
489    /// # Examples
490    ///
491    /// ```
492    /// # use rama_http_types::*;
493    /// let response: Response<String> = Response::default();
494    /// assert!(response.body().is_empty());
495    /// ```
496    #[inline]
497    pub fn body(&self) -> &T {
498        &self.body
499    }
500
501    /// Returns a mutable reference to the associated HTTP body.
502    ///
503    /// # Examples
504    ///
505    /// ```
506    /// # use rama_http_types::*;
507    /// let mut response: Response<String> = Response::default();
508    /// response.body_mut().push_str("hello world");
509    /// assert!(!response.body().is_empty());
510    /// ```
511    #[inline]
512    pub fn body_mut(&mut self) -> &mut T {
513        &mut self.body
514    }
515
516    /// Consumes the response, returning just the body.
517    ///
518    /// # Examples
519    ///
520    /// ```
521    /// # use rama_http_types::Response;
522    /// let response = Response::new(10);
523    /// let body = response.into_body();
524    /// assert_eq!(body, 10);
525    /// ```
526    #[inline]
527    pub fn into_body(self) -> T {
528        self.body
529    }
530
531    /// Consumes the response returning the head and body parts.
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// # use rama_http_types::*;
537    /// let response: Response<()> = Response::default();
538    /// let (parts, body) = response.into_parts();
539    /// assert_eq!(parts.status, StatusCode::OK);
540    /// ```
541    #[inline]
542    pub fn into_parts(self) -> (Parts, T) {
543        (self.head, self.body)
544    }
545
546    /// Consumes the response returning a new response with body mapped to the
547    /// return type of the passed in function.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// # use rama_http_types::*;
553    /// let response = Response::builder().body("some string").unwrap();
554    /// let mapped_response: Response<&[u8]> = response.map(|b| {
555    ///   assert_eq!(b, "some string");
556    ///   b.as_bytes()
557    /// });
558    /// assert_eq!(mapped_response.body(), &"some string".as_bytes());
559    /// ```
560    #[inline]
561    pub fn map<F, U>(self, f: F) -> Response<U>
562    where
563        F: FnOnce(T) -> U,
564    {
565        Response {
566            body: f(self.body),
567            head: self.head,
568        }
569    }
570
571    generate_set_and_with! {
572        pub fn extensions(mut self, extensions: Extensions) -> Self {
573            self.head.extensions = extensions;
574            self
575        }
576    }
577
578    /// Replace this response's [`Extensions`] with a [`fork`][Extensions::fork] of them, returning
579    /// the original store.
580    ///
581    /// See [`Request::fork_extensions_in_place`](crate::Request::fork_extensions_in_place).
582    #[must_use]
583    pub fn fork_extensions_in_place(&mut self) -> Extensions {
584        let child = self.head.extensions.fork();
585        core::mem::replace(&mut self.head.extensions, child)
586    }
587}
588
589impl<T: Default> Default for Response<T> {
590    #[inline]
591    fn default() -> Self {
592        Self::new(T::default())
593    }
594}
595
596impl<T: fmt::Debug> fmt::Debug for Response<T> {
597    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
598        f.debug_struct("Response")
599            .field("status", &self.status())
600            .field("version", &self.version())
601            .field("headers", self.headers())
602            // omits Extensions because not useful
603            .field("body", self.body())
604            .finish()
605    }
606}
607
608impl<T> ExtensionsRef for Response<T> {
609    fn extensions(&self) -> &Extensions {
610        &self.head.extensions
611    }
612}
613
614#[derive(Debug)]
615/// Error generated by a client or server status code.
616pub struct StatusCodeError {
617    status: StatusCode,
618    reason: Option<Cow<'static, str>>,
619}
620
621impl StatusCodeError {
622    pub fn status(&self) -> StatusCode {
623        self.status
624    }
625
626    pub fn reason(&self) -> Option<&str> {
627        self.reason.as_deref()
628    }
629}
630
631impl Display for StatusCodeError {
632    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
633        if self.status.is_client_error() {
634            write!(
635                f,
636                "http client error: status={}; reason: '{}'",
637                self.status,
638                self.reason.as_deref().unwrap_or_default(),
639            )
640        } else if self.status.is_server_error() {
641            write!(
642                f,
643                "http server error: status={}; reason: '{}'",
644                self.status,
645                self.reason.as_deref().unwrap_or_default(),
646            )
647        } else {
648            write!(
649                f,
650                "http error: status={}; reason: '{}'",
651                self.status,
652                self.reason.as_deref().unwrap_or_default(),
653            )
654        }
655    }
656}
657
658impl std::error::Error for StatusCodeError {}
659
660impl Parts {
661    /// Creates a new default instance of `Parts`
662    fn new() -> Self {
663        Self {
664            status: StatusCode::default(),
665            version: Version::default(),
666            headers: HeaderMap::default(),
667            extensions: Extensions::default(),
668        }
669    }
670}
671
672impl fmt::Debug for Parts {
673    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
674        f.debug_struct("Parts")
675            .field("status", &self.status)
676            .field("version", &self.version)
677            .field("headers", &self.headers)
678            // omits Extensions because not useful
679            // omits _priv because not useful
680            .finish()
681    }
682}
683
684impl Builder {
685    /// Creates a new default instance of `Builder` to construct either a
686    /// `Head` or a `Response`.
687    ///
688    /// # Examples
689    ///
690    /// ```
691    /// # use rama_http_types::*;
692    ///
693    /// let response = response::Builder::new()
694    ///     .status(200)
695    ///     .body(())
696    ///     .unwrap();
697    /// ```
698    #[inline]
699    pub fn new() -> Self {
700        Self::default()
701    }
702
703    #[inline]
704    /// Same as [`Self::new`] but with the given [`Extensions`] to start from.
705    pub fn new_with_extensions(ext: Extensions) -> Self {
706        Self {
707            inner: Ok(Parts {
708                status: StatusCode::default(),
709                version: Version::default(),
710                headers: HeaderMap::default(),
711                extensions: ext,
712            }),
713        }
714    }
715
716    /// Set the HTTP status for this response.
717    ///
718    /// By default this is `200`.
719    ///
720    /// # Examples
721    ///
722    /// ```
723    /// # use rama_http_types::*;
724    ///
725    /// let response = Response::builder()
726    ///     .status(200)
727    ///     .body(())
728    ///     .unwrap();
729    /// ```
730    pub fn status<T>(self, status: T) -> Self
731    where
732        T: TryInto<StatusCode>,
733        <T as TryInto<StatusCode>>::Error: Into<crate::Error>,
734    {
735        self.and_then(move |mut head| {
736            head.status = status.try_into().map_err(Into::into)?;
737            Ok(head)
738        })
739    }
740
741    /// Set the HTTP version for this response.
742    ///
743    /// By default this is HTTP/1.1
744    ///
745    /// # Examples
746    ///
747    /// ```
748    /// # use rama_http_types::*;
749    ///
750    /// let response = Response::builder()
751    ///     .version(Version::HTTP_2)
752    ///     .body(())
753    ///     .unwrap();
754    /// ```
755    pub fn version(self, version: Version) -> Self {
756        self.and_then(move |mut head| {
757            head.version = version;
758            Ok(head)
759        })
760    }
761
762    /// Appends a header to this response builder.
763    ///
764    /// This function will append the provided key/value as a header to the
765    /// internal `HeaderMap` being constructed. Essentially this is equivalent
766    /// to calling `HeaderMap::append`.
767    ///
768    /// # Examples
769    ///
770    /// ```
771    /// # use rama_http_types::*;
772    /// # use rama_http_types::header::HeaderValue;
773    ///
774    /// let response = Response::builder()
775    ///     .header("Content-Type", "text/html")
776    ///     .header("X-Custom-Foo", "bar")
777    ///     .header("content-length", 0)
778    ///     .body(())
779    ///     .unwrap();
780    /// ```
781    pub fn header<K, V>(self, key: K, value: V) -> Self
782    where
783        K: TryInto<HeaderName>,
784        <K as TryInto<HeaderName>>::Error: Into<crate::Error>,
785        V: TryInto<HeaderValue>,
786        <V as TryInto<HeaderValue>>::Error: Into<crate::Error>,
787    {
788        self.and_then(move |mut head| {
789            let name = key.try_into().map_err(Into::into)?;
790            let value = value.try_into().map_err(Into::into)?;
791            head.headers.try_append(name, value)?;
792            Ok(head)
793        })
794    }
795
796    /// Get header on this response builder.
797    ///
798    /// When builder has error returns None.
799    ///
800    /// # Example
801    ///
802    /// ```
803    /// # use rama_http_types::Response;
804    /// # use rama_http_types::header::HeaderValue;
805    /// let res = Response::builder()
806    ///     .header("Accept", "text/html")
807    ///     .header("X-Custom-Foo", "bar");
808    /// let headers = res.headers_ref().unwrap();
809    /// assert_eq!( headers["Accept"], "text/html" );
810    /// assert_eq!( headers["X-Custom-Foo"], "bar" );
811    /// ```
812    #[must_use]
813    pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
814        self.inner.as_ref().ok().map(|h| &h.headers)
815    }
816
817    /// Get header on this response builder.
818    /// when builder has error returns None
819    ///
820    /// # Example
821    ///
822    /// ```
823    /// # use rama_http_types::*;
824    /// # use rama_http_types::header::HeaderValue;
825    /// # use rama_http_types::response::Builder;
826    /// let mut res = Response::builder();
827    /// {
828    ///   let headers = res.headers_mut().unwrap();
829    ///   headers.insert("Accept", HeaderValue::from_static("text/html"));
830    ///   headers.insert("X-Custom-Foo", HeaderValue::from_static("bar"));
831    /// }
832    /// let headers = res.headers_ref().unwrap();
833    /// assert_eq!( headers["Accept"], "text/html" );
834    /// assert_eq!( headers["X-Custom-Foo"], "bar" );
835    /// ```
836    pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
837        self.inner.as_mut().ok().map(|h| &mut h.headers)
838    }
839
840    /// Adds an extension to this builder
841    ///
842    /// # Examples
843    ///
844    /// ```
845    /// # use rama_http_types::Response;
846    /// # use rama_core::extensions::{Extension, ExtensionsRef as _};
847    ///
848    /// #[derive(Debug, Clone, PartialEq)]
849    /// struct MyExtension(&'static str);
850    /// impl Extension for MyExtension {}
851    ///
852    /// let response = Response::builder()
853    ///     .extension(MyExtension("My Extension"))
854    ///     .body(())
855    ///     .unwrap();
856    ///
857    /// assert_eq!(response.extensions().get_ref::<MyExtension>(),
858    ///            Some(&MyExtension("My Extension")));
859    /// ```
860    pub fn extension<T>(self, extension: T) -> Self
861    where
862        T: Extension,
863    {
864        self.and_then(move |head| {
865            head.extensions.insert(extension);
866            Ok(head)
867        })
868    }
869
870    /// Get a reference to the extensions for this response builder.
871    ///
872    /// If the builder has an error, this returns `None`.
873    ///
874    /// # Example
875    ///
876    /// ```
877    /// # use rama_http_types::Response;
878    /// # use rama_core::extensions::Extension;
879    /// #[derive(Debug, Clone, PartialEq)]
880    /// struct MyExtension(&'static str);
881    /// impl Extension for MyExtension {}
882    ///
883    /// #[derive(Debug, Clone, PartialEq)]
884    /// struct MyCount(u32);
885    /// impl Extension for MyCount {}
886    ///
887    /// let res = Response::builder().extension(MyExtension("My Extension")).extension(MyCount(5));
888    /// let extensions = res.extensions().unwrap();
889    /// assert_eq!(extensions.get_ref::<MyExtension>(), Some(&MyExtension("My Extension")));
890    /// assert_eq!(extensions.get_ref::<MyCount>(), Some(&MyCount(5)));
891    /// ```
892    #[must_use]
893    pub fn extensions(&self) -> Option<&Extensions> {
894        self.inner.as_ref().ok().map(|h| &h.extensions)
895    }
896
897    /// "Consumes" this builder, using the provided `body` to return a
898    /// constructed `Response`.
899    ///
900    /// # Errors
901    ///
902    /// This function may return an error if any previously configured argument
903    /// failed to parse or get converted to the internal representation. For
904    /// example if an invalid `head` was specified via `header("Foo",
905    /// "Bar\r\n")` the error will be returned when this function is called
906    /// rather than when `header` was called.
907    ///
908    /// # Examples
909    ///
910    /// ```
911    /// # use rama_http_types::*;
912    ///
913    /// let response = Response::builder()
914    ///     .body(())
915    ///     .unwrap();
916    /// ```
917    pub fn body<T>(self, body: T) -> Result<Response<T>> {
918        self.inner.map(move |head| Response { head, body })
919    }
920
921    // private
922
923    fn and_then<F>(self, func: F) -> Self
924    where
925        F: FnOnce(Parts) -> Result<Parts>,
926    {
927        Self {
928            inner: self.inner.and_then(func),
929        }
930    }
931}
932
933impl Default for Builder {
934    #[inline]
935    fn default() -> Self {
936        Self {
937            inner: Ok(Parts::new()),
938        }
939    }
940}
941
942#[cfg(test)]
943mod tests {
944    use super::*;
945
946    #[test]
947    fn it_can_map_a_body_from_one_type_to_another() {
948        let response = Response::builder().body("some string").unwrap();
949        let mapped_response = response.map(|s| {
950            assert_eq!(s, "some string");
951            123u32
952        });
953        assert_eq!(mapped_response.body(), &123u32);
954    }
955
956    #[test]
957    fn fork_extensions_in_place_isolates_the_child_from_the_parent() {
958        #[derive(Debug, Extension)]
959        struct Source;
960        #[derive(Debug, Extension)]
961        struct Child;
962
963        let mut response = Response::new(());
964        response.extensions().insert(Source);
965
966        let parent = response.fork_extensions_in_place();
967        response.extensions().insert(Child);
968
969        assert!(response.extensions().contains::<Source>());
970        assert!(!parent.contains::<Child>());
971
972        // ... so a second child forks from an untouched parent
973        response.set_extensions(parent.fork());
974        assert!(response.extensions().contains::<Source>());
975        assert!(!response.extensions().contains::<Child>());
976    }
977}