diff --git a/src/body.rs b/src/body.rs index 0989611b1..8b8bb6270 100644 --- a/src/body.rs +++ b/src/body.rs @@ -6,7 +6,7 @@ use route::Frame; /// Represents various types of http message body. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Body { /// Empty response. `Content-Length` header is set to `0` Empty, @@ -23,7 +23,7 @@ pub enum Body { /// Represents various types of binary body. /// `Content-Length` header is set to length of the body. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Binary { /// Bytes body Bytes(Bytes), diff --git a/src/httpresponse.rs b/src/httpresponse.rs index 154240058..1c9877fb9 100644 --- a/src/httpresponse.rs +++ b/src/httpresponse.rs @@ -5,6 +5,8 @@ use std::convert::Into; use cookie::CookieJar; use http::{StatusCode, Version, HeaderMap, HttpTryFrom, Error as HttpError}; use http::header::{self, HeaderName, HeaderValue}; +use serde_json; +use serde::Serialize; use Cookie; use body::Body; @@ -400,7 +402,8 @@ impl HttpResponseBuilder { self } - /// Set a body + /// Set a body and generate `HttpResponse`. + /// `HttpResponseBuilder` can not be used after this call. pub fn body>(&mut self, body: B) -> Result { let mut parts = self.parts.take().expect("cannot reuse response builder"); if let Some(e) = self.err.take() { @@ -425,7 +428,23 @@ impl HttpResponseBuilder { }) } - /// Set an empty body + /// Set a json body and generate `HttpResponse` + pub fn json(&mut self, value: T) -> Result { + let body = serde_json::to_string(&value)?; + + let contains = if let Some(parts) = parts(&mut self.parts, &self.err) { + parts.headers.contains_key(header::CONTENT_TYPE) + } else { + true + }; + if !contains { + self.header(header::CONTENT_TYPE, "application/json"); + } + + Ok(self.body(body)?) + } + + /// Set an empty body and generate `HttpResponse` pub fn finish(&mut self) -> Result { self.body(Body::Empty) } @@ -442,6 +461,7 @@ fn parts<'a>(parts: &'a mut Option, err: &Option) -> Option<&' #[cfg(test)] mod tests { use super::*; + use bytes::Bytes; #[test] fn test_body() { @@ -479,4 +499,23 @@ mod tests { .content_encoding(ContentEncoding::Br).finish().unwrap(); assert_eq!(*resp.content_encoding(), ContentEncoding::Br); } + + #[test] + fn test_json() { + let resp = HttpResponse::build(StatusCode::OK) + .json(vec!["v1", "v2", "v3"]).unwrap(); + let ct = resp.headers().get(header::CONTENT_TYPE).unwrap(); + assert_eq!(ct, header::HeaderValue::from_static("application/json")); + assert_eq!(*resp.body(), Body::from(Bytes::from_static(b"[\"v1\",\"v2\",\"v3\"]"))); + } + + #[test] + fn test_json_ct() { + let resp = HttpResponse::build(StatusCode::OK) + .header(header::CONTENT_TYPE, "text/json") + .json(vec!["v1", "v2", "v3"]).unwrap(); + let ct = resp.headers().get(header::CONTENT_TYPE).unwrap(); + assert_eq!(ct, header::HeaderValue::from_static("text/json")); + assert_eq!(*resp.body(), Body::from(Bytes::from_static(b"[\"v1\",\"v2\",\"v3\"]"))); + } }