mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-04-19 22:44:38 +00:00
use Into<hyper::Body> for Response
This commit is contained in:
parent
9e9b8869c9
commit
3a03dc60fa
2 changed files with 46 additions and 32 deletions
|
@ -1,6 +1,7 @@
|
|||
use crate::{ResourceType, StatusCode};
|
||||
#[cfg(feature = "openapi")]
|
||||
use crate::{OpenapiSchema, OpenapiType};
|
||||
use hyper::Body;
|
||||
use mime::{Mime, APPLICATION_JSON};
|
||||
#[cfg(feature = "openapi")]
|
||||
use openapiv3::{SchemaKind, StringFormat, StringType, Type, VariantOrUnknownOrEmpty};
|
||||
|
@ -8,41 +9,54 @@ use serde::Serialize;
|
|||
use serde_json::error::Error as SerdeJsonError;
|
||||
use std::error::Error;
|
||||
|
||||
/// A response, used to create the final gotham response from.
|
||||
pub struct Response
|
||||
{
|
||||
pub status : StatusCode,
|
||||
pub body : String,
|
||||
pub body : Body,
|
||||
pub mime : Option<Mime>
|
||||
}
|
||||
|
||||
impl Response
|
||||
{
|
||||
pub fn new(status : StatusCode, body : String, mime : Option<Mime>) -> Self
|
||||
/// Create a new `Response` from raw data.
|
||||
pub fn new<B : Into<Body>>(status : StatusCode, body : B, mime : Option<Mime>) -> Self
|
||||
{
|
||||
Self {
|
||||
status,
|
||||
body,
|
||||
body: body.into(),
|
||||
mime
|
||||
}
|
||||
}
|
||||
|
||||
pub fn json(status : StatusCode, body : String) -> Self
|
||||
/// Create a `Response` with mime type json from already serialized data.
|
||||
pub fn json<B : Into<Body>>(status : StatusCode, body : B) -> Self
|
||||
{
|
||||
Self {
|
||||
status,
|
||||
body,
|
||||
body: body.into(),
|
||||
mime: Some(APPLICATION_JSON)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a _204 No Content_ `Response`.
|
||||
pub fn no_content() -> Self
|
||||
{
|
||||
Self {
|
||||
status: StatusCode::NO_CONTENT,
|
||||
body: String::new(),
|
||||
body: Body::empty(),
|
||||
mime: None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn full_body(self) -> Vec<u8>
|
||||
{
|
||||
use futures::{future::Future, stream::Stream};
|
||||
|
||||
let bytes : &[u8] = &self.body.concat2().wait().unwrap().into_bytes();
|
||||
bytes.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait provided to convert a resource's result to json.
|
||||
|
@ -50,7 +64,7 @@ pub trait ResourceResult
|
|||
{
|
||||
/// Turn this into a response that can be returned to the browser. This api will likely
|
||||
/// change in the future.
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>;
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>;
|
||||
|
||||
/// Return a list of supported mime types.
|
||||
fn accepted_types() -> Option<Vec<Mime>>
|
||||
|
@ -98,10 +112,10 @@ impl<T : ToString> From<T> for ResourceError
|
|||
|
||||
impl<R : ResourceType, E : Error> ResourceResult for Result<R, E>
|
||||
{
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>
|
||||
{
|
||||
Ok(match self {
|
||||
Ok(r) => Response::json(StatusCode::OK, serde_json::to_string(r)?),
|
||||
Ok(r) => Response::json(StatusCode::OK, serde_json::to_string(&r)?),
|
||||
Err(e) => {
|
||||
let err : ResourceError = e.into();
|
||||
Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?)
|
||||
|
@ -158,7 +172,7 @@ impl<T> From<T> for Success<T>
|
|||
|
||||
impl<T : ResourceType> ResourceResult for Success<T>
|
||||
{
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>
|
||||
{
|
||||
Ok(Response::json(StatusCode::OK, serde_json::to_string(&self.0)?))
|
||||
}
|
||||
|
@ -208,7 +222,7 @@ impl From<()> for NoContent
|
|||
impl ResourceResult for NoContent
|
||||
{
|
||||
/// This will always be a _204 No Content_ together with an empty string.
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>
|
||||
{
|
||||
Ok(Response::no_content())
|
||||
}
|
||||
|
@ -230,10 +244,10 @@ impl ResourceResult for NoContent
|
|||
|
||||
impl<E : Error> ResourceResult for Result<NoContent, E>
|
||||
{
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>
|
||||
{
|
||||
match self {
|
||||
Ok(nc) => nc.to_response(),
|
||||
Ok(nc) => nc.into_response(),
|
||||
Err(e) => {
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
|
@ -268,11 +282,11 @@ impl<T> Raw<T>
|
|||
}
|
||||
}
|
||||
|
||||
impl<T : ToString> ResourceResult for Raw<T>
|
||||
impl<T : Into<Body>> ResourceResult for Raw<T>
|
||||
{
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>
|
||||
{
|
||||
Ok(Response::new(StatusCode::OK, self.raw.to_string(), Some(self.mime.clone())))
|
||||
Ok(Response::new(StatusCode::OK, self.raw, Some(self.mime.clone())))
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
|
@ -290,10 +304,10 @@ impl<T, E : Error> ResourceResult for Result<Raw<T>, E>
|
|||
where
|
||||
Raw<T> : ResourceResult
|
||||
{
|
||||
fn to_response(&self) -> Result<Response, SerdeJsonError>
|
||||
fn into_response(self) -> Result<Response, SerdeJsonError>
|
||||
{
|
||||
match self {
|
||||
Ok(raw) => raw.to_response(),
|
||||
Ok(raw) => raw.into_response(),
|
||||
Err(e) => {
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
|
@ -331,50 +345,50 @@ mod test
|
|||
fn resource_result_ok()
|
||||
{
|
||||
let ok : Result<Msg, MsgError> = Ok(Msg::default());
|
||||
let res = ok.to_response().expect("didn't expect error response");
|
||||
let res = ok.into_response().expect("didn't expect error response");
|
||||
assert_eq!(res.status, StatusCode::OK);
|
||||
assert_eq!(res.body, r#"{"msg":""}"#);
|
||||
assert_eq!(res.mime, Some(APPLICATION_JSON));
|
||||
assert_eq!(res.full_body(), r#"{"msg":""}"#.as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resource_result_err()
|
||||
{
|
||||
let err : Result<Msg, MsgError> = Err(MsgError::default());
|
||||
let res = err.to_response().expect("didn't expect error response");
|
||||
let res = err.into_response().expect("didn't expect error response");
|
||||
assert_eq!(res.status, StatusCode::INTERNAL_SERVER_ERROR);
|
||||
assert_eq!(res.body, format!(r#"{{"error":true,"message":"{}"}}"#, err.unwrap_err()));
|
||||
assert_eq!(res.mime, Some(APPLICATION_JSON));
|
||||
assert_eq!(res.full_body(), format!(r#"{{"error":true,"message":"{}"}}"#, MsgError::default()).as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn success_always_successfull()
|
||||
{
|
||||
let success : Success<Msg> = Msg::default().into();
|
||||
let res = success.to_response().expect("didn't expect error response");
|
||||
let res = success.into_response().expect("didn't expect error response");
|
||||
assert_eq!(res.status, StatusCode::OK);
|
||||
assert_eq!(res.body, r#"{"msg":""}"#);
|
||||
assert_eq!(res.mime, Some(APPLICATION_JSON));
|
||||
assert_eq!(res.full_body(), r#"{"msg":""}"#.as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_content_has_empty_response()
|
||||
{
|
||||
let no_content = NoContent::default();
|
||||
let res = no_content.to_response().expect("didn't expect error response");
|
||||
let res = no_content.into_response().expect("didn't expect error response");
|
||||
assert_eq!(res.status, StatusCode::NO_CONTENT);
|
||||
assert_eq!(res.body, "");
|
||||
assert_eq!(res.mime, None);
|
||||
assert_eq!(res.full_body(), &[] as &[u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_content_result()
|
||||
{
|
||||
let no_content : Result<NoContent, MsgError> = Ok(NoContent::default());
|
||||
let res = no_content.to_response().expect("didn't expect error response");
|
||||
let res = no_content.into_response().expect("didn't expect error response");
|
||||
assert_eq!(res.status, StatusCode::NO_CONTENT);
|
||||
assert_eq!(res.body, "");
|
||||
assert_eq!(res.mime, None);
|
||||
assert_eq!(res.full_body(), &[] as &[u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -382,9 +396,9 @@ mod test
|
|||
{
|
||||
let msg = "Test";
|
||||
let raw = Raw::new(msg, TEXT_PLAIN);
|
||||
let res = raw.to_response().expect("didn't expect error response");
|
||||
let res = raw.into_response().expect("didn't expect error response");
|
||||
assert_eq!(res.status, StatusCode::OK);
|
||||
assert_eq!(res.body, msg);
|
||||
assert_eq!(res.mime, Some(TEXT_PLAIN));
|
||||
assert_eq!(res.full_body(), msg.as_bytes());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ where
|
|||
F : FnOnce(&mut State) -> R,
|
||||
R : ResourceResult
|
||||
{
|
||||
let res = get_result(&mut state).to_response();
|
||||
let res = get_result(&mut state).into_response();
|
||||
match res {
|
||||
Ok(res) => {
|
||||
let r = response_from(res, &state);
|
||||
|
@ -170,7 +170,7 @@ where
|
|||
}
|
||||
};
|
||||
|
||||
let res = get_result(&mut state, body).to_response();
|
||||
let res = get_result(&mut state, body).into_response();
|
||||
match res {
|
||||
Ok(res) => {
|
||||
let r = response_from(res, &state);
|
||||
|
|
Loading…
Add table
Reference in a new issue