diff --git a/gotham_restful/src/lib.rs b/gotham_restful/src/lib.rs index 25530e4..9fd913c 100644 --- a/gotham_restful/src/lib.rs +++ b/gotham_restful/src/lib.rs @@ -114,7 +114,9 @@ pub use resource::{ mod result; pub use result::{ NoContent, + Raw, ResourceResult, + Response, Success }; diff --git a/gotham_restful/src/result.rs b/gotham_restful/src/result.rs index 6158147..610b8f3 100644 --- a/gotham_restful/src/result.rs +++ b/gotham_restful/src/result.rs @@ -2,6 +2,8 @@ use crate::{ResourceType, StatusCode}; #[cfg(feature = "openapi")] use crate::{OpenapiSchema, OpenapiType}; use mime::{Mime, APPLICATION_JSON}; +#[cfg(feature = "openapi")] +use openapiv3::{SchemaKind, StringFormat, StringType, Type, VariantOrUnknownOrEmpty}; use serde::Serialize; use serde_json::error::Error as SerdeJsonError; use std::error::Error; @@ -15,6 +17,15 @@ pub struct Response impl Response { + pub fn new(status : StatusCode, body : String, mime : Option) -> Self + { + Self { + status, + body, + mime + } + } + pub fn json(status : StatusCode, body : String) -> Self { Self { @@ -243,10 +254,66 @@ impl ResourceResult for Result } } +pub struct Raw +{ + pub raw : T, + pub mime : Mime +} + +impl Raw +{ + pub fn new(raw : T, mime : Mime) -> Self + { + Self { raw, mime } + } +} + +impl ResourceResult for Raw +{ + fn to_response(&self) -> Result + { + Ok(Response::new(StatusCode::OK, self.raw.to_string(), Some(self.mime.clone()))) + } + + #[cfg(feature = "openapi")] + fn schema() -> OpenapiSchema + { + OpenapiSchema::new(SchemaKind::Type(Type::String(StringType { + format: VariantOrUnknownOrEmpty::Item(StringFormat::Binary), + pattern: None, + enumeration: Vec::new() + }))) + } +} + +impl ResourceResult for Result, E> +where + Raw : ResourceResult +{ + fn to_response(&self) -> Result + { + match self { + Ok(raw) => raw.to_response(), + Err(e) => { + let err : ResourceError = e.into(); + Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?)) + } + } + } + + #[cfg(feature = "openapi")] + fn schema() -> OpenapiSchema + { + as ResourceResult>::schema() + } +} + + #[cfg(test)] mod test { use super::*; + use mime::TEXT_PLAIN; use thiserror::Error; #[derive(Debug, Default, Deserialize, Serialize)] @@ -309,4 +376,15 @@ mod test assert_eq!(res.body, ""); assert_eq!(res.mime, None); } + + #[test] + fn raw_response() + { + let msg = "Test"; + let raw = Raw::new(msg, TEXT_PLAIN); + let res = raw.to_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)); + } }