1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

hellper method for json body

This commit is contained in:
Nikolay Kim 2017-11-27 10:39:47 -08:00
parent 42716d3252
commit b5a4f6f855
2 changed files with 43 additions and 4 deletions

View File

@ -6,7 +6,7 @@ use route::Frame;
/// Represents various types of http message body. /// Represents various types of http message body.
#[derive(Debug)] #[derive(Debug, PartialEq)]
pub enum Body { pub enum Body {
/// Empty response. `Content-Length` header is set to `0` /// Empty response. `Content-Length` header is set to `0`
Empty, Empty,
@ -23,7 +23,7 @@ pub enum Body {
/// Represents various types of binary body. /// Represents various types of binary body.
/// `Content-Length` header is set to length of the body. /// `Content-Length` header is set to length of the body.
#[derive(Debug)] #[derive(Debug, PartialEq)]
pub enum Binary { pub enum Binary {
/// Bytes body /// Bytes body
Bytes(Bytes), Bytes(Bytes),

View File

@ -5,6 +5,8 @@ use std::convert::Into;
use cookie::CookieJar; use cookie::CookieJar;
use http::{StatusCode, Version, HeaderMap, HttpTryFrom, Error as HttpError}; use http::{StatusCode, Version, HeaderMap, HttpTryFrom, Error as HttpError};
use http::header::{self, HeaderName, HeaderValue}; use http::header::{self, HeaderName, HeaderValue};
use serde_json;
use serde::Serialize;
use Cookie; use Cookie;
use body::Body; use body::Body;
@ -400,7 +402,8 @@ impl HttpResponseBuilder {
self self
} }
/// Set a body /// Set a body and generate `HttpResponse`.
/// `HttpResponseBuilder` can not be used after this call.
pub fn body<B: Into<Body>>(&mut self, body: B) -> Result<HttpResponse, HttpError> { pub fn body<B: Into<Body>>(&mut self, body: B) -> Result<HttpResponse, HttpError> {
let mut parts = self.parts.take().expect("cannot reuse response builder"); let mut parts = self.parts.take().expect("cannot reuse response builder");
if let Some(e) = self.err.take() { 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<T: Serialize>(&mut self, value: T) -> Result<HttpResponse, Error> {
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<HttpResponse, HttpError> { pub fn finish(&mut self) -> Result<HttpResponse, HttpError> {
self.body(Body::Empty) self.body(Body::Empty)
} }
@ -442,6 +461,7 @@ fn parts<'a>(parts: &'a mut Option<Parts>, err: &Option<HttpError>) -> Option<&'
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use bytes::Bytes;
#[test] #[test]
fn test_body() { fn test_body() {
@ -479,4 +499,23 @@ mod tests {
.content_encoding(ContentEncoding::Br).finish().unwrap(); .content_encoding(ContentEncoding::Br).finish().unwrap();
assert_eq!(*resp.content_encoding(), ContentEncoding::Br); 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\"]")));
}
} }