use actix_web::{http::StatusCode, Error, HttpRequest, HttpResponse, Responder}; use serde::Serialize; pub struct FormatMsg { pub message: T, pub code: StatusCode, } impl FormatMsg { /// Deconstruct to an inner value pub fn into_inner(self) -> T { self.message } pub fn ok(message: T) -> Self { FormatMsg { message: message, code: StatusCode::OK, } } } impl Responder for FormatMsg { type Error = Error; type Future = Result; fn respond_to(self, _: &HttpRequest) -> Self::Future { let body = match serde_json::to_string(&self.message) { Ok(body) => body, Err(e) => return Err(e.into()), }; Ok(HttpResponse::build(self.code) .content_type("application/json") .body(body)) } } #[cfg(test)] mod tests { use super::*; use crate::routes::*; use crate::routes::tests::*; use serde::ser::{Error, Serializer}; #[test] fn test_into_inner() { // Arrange let msg = NotUnderstood {path: vec![]}; let msg_ref = msg.clone(); let formatted = FormatMsg { message: msg.as_outgoing(), code: StatusCode::OK, }; // Act let result = formatted.into_inner(); // Assert assert_eq!(result.result_type, "NOT_UNDERSTOOD"); assert_eq!(result.content, msg_ref); } #[test] fn test_ok() { // Arrange let msg = NotUnderstood {path: vec![]}; let msg_ref = msg.clone(); // Act let result = FormatMsg::ok(msg); // Assert assert_eq!(result.message, msg_ref); assert_eq!(result.code, StatusCode::OK); } #[test] fn test_responder() { // Arrange let msg = NotUnderstood {path: vec![]}; let msg_ref = msg.clone(); let formatted = FormatMsg { message: msg, code: StatusCode::NOT_FOUND, }; let request = gen_request("/api/404", None); // Act let result = &formatted.respond_to(&request).unwrap(); // Assert assert_eq!(result.status(), StatusCode::NOT_FOUND); assert_eq!(result.headers().get("content-type").unwrap(), "application/json"); let content = get_message::(result); assert_eq!(content, msg_ref); } struct InvalidMessage {} impl Serialize for InvalidMessage { fn serialize(&self, _: S) -> Result where S: Serializer { Err(Error::custom("oops".to_string())) } } #[test] fn test_responder_serde_error() { // Arrange let msg = InvalidMessage {}; let formatted = FormatMsg { message: msg, code: StatusCode::NOT_FOUND, }; let request = gen_request("/api/404", None); // Act let result = formatted.respond_to(&request); // Assert assert!(result.is_err()); } }