2 use serde_json
::{json, Value}
;
4 use hyper
::{Body, Response, StatusCode}
;
7 use proxmox
::api
::{HttpError, RpcEnvironment}
;
9 /// Extension to set error message for server side logging
10 pub struct ErrorMessageExtension(pub String
);
12 pub struct OutputFormatter
{
14 pub format_data
: fn(data
: Value
, rpcenv
: &dyn RpcEnvironment
) -> Response
<Body
>,
16 pub format_error
: fn(err
: Error
) -> Response
<Body
>,
19 static JSON_CONTENT_TYPE
: &str = "application/json;charset=UTF-8";
21 pub fn json_response(result
: Result
<Value
, Error
>) -> Response
<Body
> {
23 Ok(data
) => json_data_response(data
),
24 Err(err
) => json_error_response(err
),
28 pub fn json_data_response(data
: Value
) -> Response
<Body
> {
30 let json_str
= data
.to_string();
32 let raw
= json_str
.into_bytes();
34 let mut response
= Response
::new(raw
.into());
35 response
.headers_mut().insert(
37 header
::HeaderValue
::from_static(JSON_CONTENT_TYPE
));
42 fn add_result_attributes(result
: &mut Value
, rpcenv
: &dyn RpcEnvironment
)
44 let attributes
= match rpcenv
.result_attrib().as_object() {
49 for (key
, value
) in attributes
{
50 result
[key
] = value
.clone();
54 fn json_format_data(data
: Value
, rpcenv
: &dyn RpcEnvironment
) -> Response
<Body
> {
56 let mut result
= json
!({
60 add_result_attributes(&mut result
, rpcenv
);
62 json_data_response(result
)
65 pub fn json_error_response(err
: Error
) -> Response
<Body
> {
67 let mut response
= if let Some(apierr
) = err
.downcast_ref
::<HttpError
>() {
68 let mut resp
= Response
::new(Body
::from(apierr
.message
.clone()));
69 *resp
.status_mut() = apierr
.code
;
72 let mut resp
= Response
::new(Body
::from(err
.to_string()));
73 *resp
.status_mut() = StatusCode
::BAD_REQUEST
;
77 response
.headers_mut().insert(
79 header
::HeaderValue
::from_static(JSON_CONTENT_TYPE
));
81 response
.extensions_mut().insert(ErrorMessageExtension(err
.to_string()));
86 pub static JSON_FORMATTER
: OutputFormatter
= OutputFormatter
{
87 format_data
: json_format_data
,
88 format_error
: json_error_response
,
91 fn extjs_format_data(data
: Value
, rpcenv
: &dyn RpcEnvironment
) -> Response
<Body
> {
93 let mut result
= json
!({
98 add_result_attributes(&mut result
, rpcenv
);
100 json_data_response(result
)
103 fn extjs_format_error(err
: Error
) -> Response
<Body
> {
105 let mut errors
= vec
![];
107 let message
= err
.to_string();
108 errors
.push(&message
);
116 let mut response
= json_data_response(result
);
118 response
.extensions_mut().insert(ErrorMessageExtension(message
));
123 pub static EXTJS_FORMATTER
: OutputFormatter
= OutputFormatter
{
124 format_data
: extjs_format_data
,
125 format_error
: extjs_format_error
,