From 53acf7490b2c5d6bc097221f7f5c0d2b4e291272 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 5 Dec 2018 12:42:25 +0100 Subject: [PATCH] add output formatter --- src/server/formatter.rs | 51 +++++++++++++++++++++++++++++++++++++++++ src/server/rest.rs | 26 +++++++++++++-------- 2 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 src/server/formatter.rs diff --git a/src/server/formatter.rs b/src/server/formatter.rs new file mode 100644 index 00000000..fa76b4c7 --- /dev/null +++ b/src/server/formatter.rs @@ -0,0 +1,51 @@ +use failure::*; +use serde_json::{json, Value}; + +pub struct OutputFormatter { + + pub format_result: fn(data: &Value) -> (Vec, &'static str), +} + +fn json_format_result(data: &Value) -> (Vec, &'static str) { + + let content_type = "application/json;charset=UTF-8"; + + let result = json!({ + "data": data + }); + + // todo: set result.total result.changes + + let json_str = result.to_string(); + + let raw = json_str.into_bytes(); + + (raw, content_type) +} + +pub static JSON_FORMATTER: OutputFormatter = OutputFormatter { + format_result: json_format_result, +}; + + +fn extjs_format_result(data: &Value) -> (Vec, &'static str) { + + let content_type = "application/json;charset=UTF-8"; + + let result = json!({ + "data": data, + "success": true + }); + + // todo: set result.total result.changes + + let json_str = result.to_string(); + + let raw = json_str.into_bytes(); + + (raw, content_type) +} + +pub static EXTJS_FORMATTER: OutputFormatter = OutputFormatter { + format_result: extjs_format_result, +}; diff --git a/src/server/rest.rs b/src/server/rest.rs index 15104074..b7b8b08c 100644 --- a/src/server/rest.rs +++ b/src/server/rest.rs @@ -1,6 +1,7 @@ use crate::api::schema::*; use crate::api::router::*; use crate::api::config::*; +use super::formatter::*; use std::fmt; use std::path::{Path, PathBuf}; @@ -66,7 +67,7 @@ impl Service for ApiService { match result { Ok(res) => Ok::<_, hyper::Error>(res), Err(err) => { - if let Some(apierr) = err.downcast_ref::() { + if let Some(apierr) = err.downcast_ref::() { let mut resp = Response::new(Body::from(apierr.message.clone())); *resp.status_mut() = apierr.code; Ok(resp) @@ -140,6 +141,7 @@ fn get_request_parameters_async( if let Some(query_str) = parts.uri.query() { for (k, v) in form_urlencoded::parse(query_str.as_bytes()).into_owned() { + if k == "_dc" { continue; } // skip extjs "disable cache" parameter param_list.push((k, v)); } } @@ -159,6 +161,7 @@ fn get_request_parameters_async( fn handle_sync_api_request( info: &'static ApiMethod, + formatter: &'static OutputFormatter, parts: Parts, req_body: Body, uri_param: HashMap, @@ -185,15 +188,16 @@ fn handle_sync_api_request( Ok(res) - }).then(|result| { + }).then(move |result| { match result { Ok(ref value) => { - let json_str = value.to_string(); + + let (raw, content_type) = (formatter.format_result)(value); Ok(Response::builder() .status(StatusCode::OK) - .header(header::CONTENT_TYPE, "application/json") - .body(Body::from(json_str))?) + .header(header::CONTENT_TYPE, content_type) + .body(Body::from(raw))?) } Err(err) => Err(http_err!(BAD_REQUEST, err.to_string())) } @@ -374,15 +378,19 @@ pub fn handle_request(api: Arc, req: Request) -> BoxFut { println!("GOT API REQUEST"); if comp_len >= 2 { let format = components[1]; - if format != "json" { - return Box::new(future::err(http_err!(BAD_REQUEST, format!("Unsupported output format '{}'.", format)))) - } + let formatter = match format { + "json" => &JSON_FORMATTER, + "extjs" => &EXTJS_FORMATTER, + _ => { + return Box::new(future::err(http_err!(BAD_REQUEST, format!("Unsupported output format '{}'.", format)))); + } + }; let mut uri_param = HashMap::new(); if let Some(api_method) = api.find_method(&components[2..], method, &mut uri_param) { // fixme: handle auth - return handle_sync_api_request(api_method, parts, body, uri_param); + return handle_sync_api_request(api_method, formatter, parts, body, uri_param); } } } else {