aboutsummaryrefslogtreecommitdiff
path: root/src/routes/format_msg.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/format_msg.rs')
-rw-r--r--src/routes/format_msg.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/routes/format_msg.rs b/src/routes/format_msg.rs
new file mode 100644
index 0000000..d7a6f05
--- /dev/null
+++ b/src/routes/format_msg.rs
@@ -0,0 +1,124 @@
+use actix_web::{http::StatusCode, Error, HttpRequest, HttpResponse, Responder};
+use serde::Serialize;
+
+pub struct FormatMsg<T> {
+ pub message: T,
+ pub code: StatusCode,
+}
+
+impl<T> FormatMsg<T> {
+ /// 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<T: Serialize> Responder for FormatMsg<T> {
+ type Error = Error;
+ type Future = Result<HttpResponse, Error>;
+
+ 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 routes::*;
+ use 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::<NotUnderstood>(result);
+ assert_eq!(content, msg_ref);
+ }
+
+ struct InvalidMessage {}
+
+ impl Serialize for InvalidMessage {
+ fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error> 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());
+ }
+} \ No newline at end of file