1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-02-23 04:52:28 +00:00

add headers to the response (#27)

This commit is contained in:
Dominic 2021-01-14 18:37:51 +01:00
parent 3600a115d0
commit 44f3c9fe84
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
9 changed files with 48 additions and 12 deletions

View file

@ -196,11 +196,11 @@ impl ErrorVariant {
quote!(#from_field.into_response_error()) quote!(#from_field.into_response_error())
}, },
(Some(_), Some(_)) => return Err(Error::new(ident.span(), "When #[from] is used, #[status] must not be used!")), (Some(_), Some(_)) => return Err(Error::new(ident.span(), "When #[from] is used, #[status] must not be used!")),
(None, Some(status)) => quote!(Ok(#krate::Response { (None, Some(status)) => quote!(Ok(#krate::Response::new(
status: { #status }.into(), { #status }.into(),
body: #krate::gotham::hyper::Body::empty(), #krate::gotham::hyper::Body::empty(),
mime: None None
})), ))),
(None, None) => return Err(Error::new(ident.span(), "Missing #[status(code)] for this variant")) (None, None) => return Err(Error::new(ident.span(), "Missing #[status(code)] for this variant"))
}; };

View file

@ -1,14 +1,23 @@
use gotham::hyper::{Body, StatusCode}; use gotham::hyper::{
header::{HeaderMap, HeaderName, HeaderValue},
Body, StatusCode
};
use mime::{Mime, APPLICATION_JSON}; use mime::{Mime, APPLICATION_JSON};
/// A response, used to create the final gotham response from. /// A response, used to create the final gotham response from.
#[derive(Debug)] #[derive(Debug)]
pub struct Response { pub struct Response {
#[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")]
pub status: StatusCode, pub status: StatusCode,
#[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")]
pub body: Body, pub body: Body,
pub mime: Option<Mime> #[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")]
pub mime: Option<Mime>,
#[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")]
pub headers: HeaderMap
} }
#[allow(deprecated)]
impl Response { impl Response {
/// Create a new [Response] from raw data. /// Create a new [Response] from raw data.
#[must_use = "Creating a response is pointless if you don't use it"] #[must_use = "Creating a response is pointless if you don't use it"]
@ -16,7 +25,8 @@ impl Response {
Self { Self {
status, status,
body: body.into(), body: body.into(),
mime mime,
headers: Default::default()
} }
} }
@ -26,7 +36,8 @@ impl Response {
Self { Self {
status, status,
body: body.into(), body: body.into(),
mime: Some(APPLICATION_JSON) mime: Some(APPLICATION_JSON),
headers: Default::default()
} }
} }
@ -36,7 +47,8 @@ impl Response {
Self { Self {
status: StatusCode::NO_CONTENT, status: StatusCode::NO_CONTENT,
body: Body::empty(), body: Body::empty(),
mime: None mime: None,
headers: Default::default()
} }
} }
@ -46,10 +58,16 @@ impl Response {
Self { Self {
status: StatusCode::FORBIDDEN, status: StatusCode::FORBIDDEN,
body: Body::empty(), body: Body::empty(),
mime: None mime: None,
headers: Default::default()
} }
} }
/// Add an HTTP header to the [Response].
pub fn add_header(&mut self, name: HeaderName, value: HeaderValue) {
self.headers.insert(name, value);
}
#[cfg(test)] #[cfg(test)]
pub(crate) fn full_body(mut self) -> Result<Vec<u8>, <Body as gotham::hyper::body::HttpBody>::Error> { pub(crate) fn full_body(mut self) -> Result<Vec<u8>, <Body as gotham::hyper::body::HttpBody>::Error> {
use futures_executor::block_on; use futures_executor::block_on;

View file

@ -99,6 +99,7 @@ fn errorlog<E: Display>(e: E) {
#[cfg(not(feature = "errorlog"))] #[cfg(not(feature = "errorlog"))]
fn errorlog<E>(_e: E) {} fn errorlog<E>(_e: E) {}
#[allow(deprecated)]
fn handle_error<E>(e: E) -> Pin<Box<dyn Future<Output = Result<Response, E::Err>> + Send>> fn handle_error<E>(e: E) -> Pin<Box<dyn Future<Output = Result<Response, E::Err>> + Send>>
where where
E: Display + IntoResponseError E: Display + IntoResponseError
@ -160,6 +161,7 @@ mod test {
struct MsgError; struct MsgError;
#[test] #[test]
#[allow(deprecated)]
fn result_from_future() { fn result_from_future() {
let nc = NoContent::default(); let nc = NoContent::default();
let res = block_on(nc.into_response()).unwrap(); let res = block_on(nc.into_response()).unwrap();

View file

@ -92,6 +92,7 @@ where
} }
#[cfg(test)] #[cfg(test)]
#[allow(deprecated)]
mod test { mod test {
use super::*; use super::*;
use futures_executor::block_on; use futures_executor::block_on;

View file

@ -131,6 +131,7 @@ mod test {
use mime::TEXT_PLAIN; use mime::TEXT_PLAIN;
#[test] #[test]
#[allow(deprecated)]
fn raw_response() { fn raw_response() {
let msg = "Test"; let msg = "Test";
let raw = Raw::new(msg, TEXT_PLAIN); let raw = Raw::new(msg, TEXT_PLAIN);

View file

@ -49,6 +49,7 @@ where
} }
#[cfg(test)] #[cfg(test)]
#[allow(deprecated)]
mod test { mod test {
use super::*; use super::*;
use crate::result::OrAllTypes; use crate::result::OrAllTypes;

View file

@ -124,6 +124,7 @@ mod test {
} }
#[test] #[test]
#[allow(deprecated)]
fn success_always_successfull() { fn success_always_successfull() {
let success: Success<Msg> = Msg::default().into(); let success: Success<Msg> = Msg::default().into();
let res = block_on(success.into_response()).expect("didn't expect error response"); let res = block_on(success.into_response()).expect("didn't expect error response");

View file

@ -81,10 +81,21 @@ pub trait DrawResourceRoutes {
fn remove<Handler: ResourceRemove>(&mut self); fn remove<Handler: ResourceRemove>(&mut self);
} }
#[allow(deprecated)]
fn response_from(res: Response, state: &State) -> gotham::hyper::Response<Body> { fn response_from(res: Response, state: &State) -> gotham::hyper::Response<Body> {
let mut r = create_empty_response(state, res.status); let mut r = create_empty_response(state, res.status);
let headers = r.headers_mut();
if let Some(mime) = res.mime { if let Some(mime) = res.mime {
r.headers_mut().insert(CONTENT_TYPE, mime.as_ref().parse().unwrap()); headers.insert(CONTENT_TYPE, mime.as_ref().parse().unwrap());
}
let mut last_name = None;
for (name, value) in res.headers {
if name.is_some() {
last_name = name;
}
// this unwrap is safe: the first item will always be Some
let name = last_name.clone().unwrap();
headers.insert(name, value);
} }
let method = Method::borrow_from(state); let method = Method::borrow_from(state);

View file

@ -10,6 +10,7 @@ enum Error {
InternalServerError(String) InternalServerError(String)
} }
#[allow(deprecated)]
mod resource_error { mod resource_error {
use super::Error; use super::Error;
use gotham::hyper::StatusCode; use gotham::hyper::StatusCode;