api: pass RpcEnvirnment to api handlers
This commit is contained in:
@ -1,79 +1,22 @@
|
||||
use failure::*;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use crate::api::router::RpcEnvironment;
|
||||
|
||||
use hyper::{Body, Response, StatusCode};
|
||||
use hyper::header;
|
||||
|
||||
pub struct OutputFormatter {
|
||||
|
||||
pub format_result: fn(data: Result<Value, Error>) -> Response<Body>,
|
||||
pub format_result: fn(data: Value, rpcenv: &RpcEnvironment) -> Response<Body>,
|
||||
|
||||
pub format_error: fn(err: Error) -> Response<Body>,
|
||||
}
|
||||
|
||||
fn json_format_result(data: Result<Value, Error>) -> Response<Body> {
|
||||
static json_content_type: &str = "application/json;charset=UTF-8";
|
||||
|
||||
let content_type = "application/json;charset=UTF-8";
|
||||
|
||||
match data {
|
||||
Ok(value) => {
|
||||
let result = json!({
|
||||
"data": value
|
||||
});
|
||||
|
||||
// todo: set result.total result.changes
|
||||
|
||||
let json_str = result.to_string();
|
||||
|
||||
let raw = json_str.into_bytes();
|
||||
|
||||
let mut response = Response::new(raw.into());
|
||||
response.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static(content_type));
|
||||
return response;
|
||||
}
|
||||
Err(err) => {
|
||||
let mut response = Response::new(Body::from(err.to_string()));
|
||||
response.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static(content_type));
|
||||
*response.status_mut() = StatusCode::BAD_REQUEST;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub static JSON_FORMATTER: OutputFormatter = OutputFormatter {
|
||||
format_result: json_format_result,
|
||||
};
|
||||
|
||||
fn extjs_format_result(data: Result<Value, Error>) -> Response<Body> {
|
||||
|
||||
let content_type = "application/json;charset=UTF-8";
|
||||
|
||||
let result = match data {
|
||||
Ok(value) => {
|
||||
let result = json!({
|
||||
"data": value,
|
||||
"success": true
|
||||
});
|
||||
|
||||
// todo: set result.total result.changes
|
||||
|
||||
result
|
||||
}
|
||||
Err(err) => {
|
||||
let mut errors = vec![];
|
||||
|
||||
errors.push(err.to_string());
|
||||
|
||||
let result = json!({
|
||||
"errors": errors,
|
||||
"success": false
|
||||
});
|
||||
|
||||
result
|
||||
}
|
||||
};
|
||||
fn json_response(result: Value) -> Response<Body> {
|
||||
|
||||
let json_str = result.to_string();
|
||||
|
||||
@ -82,10 +25,77 @@ fn extjs_format_result(data: Result<Value, Error>) -> Response<Body> {
|
||||
let mut response = Response::new(raw.into());
|
||||
response.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static(content_type));
|
||||
header::HeaderValue::from_static(json_content_type));
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
fn json_format_result(data: Value, rpcenv: &RpcEnvironment) -> Response<Body> {
|
||||
|
||||
let mut result = json!({
|
||||
"data": data
|
||||
});
|
||||
|
||||
if let Some(total) = rpcenv.get_result_attrib("total").and_then(|v| v.as_u64()) {
|
||||
result["total"] = Value::from(total);
|
||||
}
|
||||
|
||||
if let Some(changes) = rpcenv.get_result_attrib("changes") {
|
||||
result["changes"] = changes.clone();
|
||||
}
|
||||
|
||||
json_response(result)
|
||||
}
|
||||
|
||||
fn json_format_error(err: Error) -> Response<Body> {
|
||||
|
||||
let mut response = Response::new(Body::from(err.to_string()));
|
||||
response.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static(json_content_type));
|
||||
*response.status_mut() = StatusCode::BAD_REQUEST;
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
pub static JSON_FORMATTER: OutputFormatter = OutputFormatter {
|
||||
format_result: json_format_result,
|
||||
format_error: json_format_error,
|
||||
};
|
||||
|
||||
fn extjs_format_result(data: Value, rpcenv: &RpcEnvironment) -> Response<Body> {
|
||||
|
||||
let mut result = json!({
|
||||
"data": data,
|
||||
"success": true
|
||||
});
|
||||
|
||||
if let Some(total) = rpcenv.get_result_attrib("total").and_then(|v| v.as_u64()) {
|
||||
result["total"] = Value::from(total);
|
||||
}
|
||||
|
||||
if let Some(changes) = rpcenv.get_result_attrib("changes") {
|
||||
result["changes"] = changes.clone();
|
||||
}
|
||||
|
||||
|
||||
json_response(result)
|
||||
}
|
||||
|
||||
fn extjs_format_error(err: Error) -> Response<Body> {
|
||||
|
||||
let mut errors = vec![];
|
||||
errors.push(err.to_string());
|
||||
|
||||
let result = json!({
|
||||
"errors": errors,
|
||||
"success": false
|
||||
});
|
||||
|
||||
json_response(result)
|
||||
}
|
||||
|
||||
pub static EXTJS_FORMATTER: OutputFormatter = OutputFormatter {
|
||||
format_result: extjs_format_result,
|
||||
format_error: extjs_format_error,
|
||||
};
|
||||
|
@ -26,6 +26,27 @@ use hyper::service::{Service, NewService};
|
||||
use hyper::rt::{Future, Stream};
|
||||
use hyper::header;
|
||||
|
||||
struct RestEnvironment {
|
||||
result_attributes: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
impl RestEnvironment {
|
||||
fn new() -> Self {
|
||||
Self { result_attributes: HashMap::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl RpcEnvironment for RestEnvironment {
|
||||
|
||||
fn set_result_attrib(&mut self, name: &str, value: Value) {
|
||||
self.result_attributes.insert(name.into(), value);
|
||||
}
|
||||
|
||||
fn get_result_attrib(&self, name: &str) -> Option<&Value> {
|
||||
self.result_attributes.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RestServer {
|
||||
pub api_config: Arc<ApiConfig>,
|
||||
}
|
||||
@ -169,10 +190,12 @@ fn handle_sync_api_request(
|
||||
|
||||
let resp = params
|
||||
.and_then(move |params| {
|
||||
let res = (info.handler)(params, info)?;
|
||||
Ok(res)
|
||||
}).then(move |result| {
|
||||
Ok((formatter.format_result)(result))
|
||||
let mut rpcenv = RestEnvironment::new();
|
||||
let resp = match (info.handler)(params, info, &mut rpcenv) {
|
||||
Ok(data) => (formatter.format_result)(data, &rpcenv),
|
||||
Err(err) => (formatter.format_error)(err),
|
||||
};
|
||||
Ok(resp)
|
||||
});
|
||||
|
||||
Box::new(resp)
|
||||
@ -203,7 +226,7 @@ fn handle_async_api_request(
|
||||
let params = match parse_parameter_strings(¶m_list, &info.parameters, true) {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
let resp = (formatter.format_result)(Err(Error::from(err)));
|
||||
let resp = (formatter.format_error)(Error::from(err));
|
||||
return Box::new(future::ok(resp));
|
||||
}
|
||||
};
|
||||
@ -211,7 +234,7 @@ fn handle_async_api_request(
|
||||
match (info.handler)(parts, req_body, params, info) {
|
||||
Ok(future) => future,
|
||||
Err(err) => {
|
||||
let resp = (formatter.format_result)(Err(Error::from(err)));
|
||||
let resp = (formatter.format_error)(Error::from(err));
|
||||
Box::new(future::ok(resp))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user