use super::{into_response_helper, ResourceResult}; #[cfg(feature = "openapi")] use crate::OpenapiSchema; use crate::{Response, ResponseBody}; use gotham::hyper::StatusCode; use mime::{Mime, APPLICATION_JSON}; use std::{ fmt::Debug, future::Future, ops::{Deref, DerefMut}, pin::Pin }; /** This can be returned from a resource when there is no cause of an error. It behaves similar to a smart pointer like box, it that it implements `AsRef`, `Deref` and the likes. Usage example: ``` # #[macro_use] extern crate gotham_restful_derive; # mod doc_tests_are_broken { # use gotham::state::State; # use gotham_restful::*; # use serde::{Deserialize, Serialize}; # # #[derive(Resource)] # #[resource(read_all)] # struct MyResource; # #[derive(Deserialize, Serialize)] # #[cfg_attr(feature = "openapi", derive(OpenapiType))] struct MyResponse { message: &'static str } #[read_all(MyResource)] fn read_all(_state: &mut State) -> Success { let res = MyResponse { message: "I'm always happy" }; res.into() } # } ``` */ #[derive(Debug)] pub struct Success(T); impl AsMut for Success { fn as_mut(&mut self) -> &mut T { &mut self.0 } } impl AsRef for Success { fn as_ref(&self) -> &T { &self.0 } } impl Deref for Success { type Target = T; fn deref(&self) -> &T { &self.0 } } impl DerefMut for Success { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } impl From for Success { fn from(t: T) -> Self { Self(t) } } impl Clone for Success { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Copy for Success {} impl Default for Success { fn default() -> Self { Self(T::default()) } } impl ResourceResult for Success where Self: Send { type Err = serde_json::Error; fn into_response(self) -> Pin> + Send>> { into_response_helper(|| Ok(Response::json(StatusCode::OK, serde_json::to_string(self.as_ref())?))) } fn accepted_types() -> Option> { Some(vec![APPLICATION_JSON]) } #[cfg(feature = "openapi")] fn schema() -> OpenapiSchema { T::schema() } } #[cfg(test)] mod test { use super::*; use crate::result::OrAllTypes; use futures_executor::block_on; #[derive(Debug, Default, Serialize)] #[cfg_attr(feature = "openapi", derive(crate::OpenapiType))] struct Msg { msg: String } #[test] fn success_always_successfull() { let success: Success = Msg::default().into(); let res = block_on(success.into_response()).expect("didn't expect error response"); assert_eq!(res.status, StatusCode::OK); assert_eq!(res.mime, Some(APPLICATION_JSON)); assert_eq!(res.full_body().unwrap(), r#"{"msg":""}"#.as_bytes()); } #[test] fn success_accepts_json() { assert!(>::accepted_types().or_all_types().contains(&APPLICATION_JSON)) } }