aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rust/fatcat-api/README.md3
-rw-r--r--rust/fatcat-api/api.yaml24
-rw-r--r--rust/fatcat-api/api/swagger.yaml42
-rw-r--r--rust/fatcat-api/examples/client.rs8
-rw-r--r--rust/fatcat-api/examples/server_lib/server.rs8
-rw-r--r--rust/fatcat-api/src/client.rs51
-rw-r--r--rust/fatcat-api/src/lib.rs16
-rw-r--r--rust/fatcat-api/src/mimetypes.rs8
-rw-r--r--rust/fatcat-api/src/models.rs13
-rw-r--r--rust/fatcat-api/src/server.rs60
-rw-r--r--rust/src/api_server.rs59
-rw-r--r--rust/src/lib.rs2
-rw-r--r--rust/tests/test_api_server.rs11
13 files changed, 296 insertions, 9 deletions
diff --git a/rust/fatcat-api/README.md b/rust/fatcat-api/README.md
index 2a969005..4b40f7ee 100644
--- a/rust/fatcat-api/README.md
+++ b/rust/fatcat-api/README.md
@@ -13,7 +13,7 @@ To see how to make this your own, look here:
[README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md)
- API version: 0.1.0
-- Build date: 2018-06-17T23:06:55.598Z
+- Build date: 2018-06-20T01:30:08.472Z
This autogenerated project defines an API crate `fatcat` which contains:
* An `Api` trait defining the API in Rust.
@@ -77,6 +77,7 @@ cargo run --example client GetEditorChangelog
cargo run --example client GetFile
cargo run --example client GetRelease
cargo run --example client GetReleaseFiles
+cargo run --example client GetStats
cargo run --example client GetWork
cargo run --example client GetWorkReleases
cargo run --example client LookupContainer
diff --git a/rust/fatcat-api/api.yaml b/rust/fatcat-api/api.yaml
index 44fde1f6..253cec04 100644
--- a/rust/fatcat-api/api.yaml
+++ b/rust/fatcat-api/api.yaml
@@ -39,7 +39,6 @@ x-entity-props: &ENTITYPROPS
type: object
additionalProperties: {}
-
definitions:
error_response:
type: object
@@ -312,6 +311,12 @@ definitions:
type: string
role:
type: string
+ stats_response:
+ type: object
+ properties:
+ extra:
+ type: object
+ additionalProperties: {}
x-entity-responses: &ENTITYRESPONSES
400:
@@ -788,3 +793,20 @@ paths:
description: Generic Error
schema:
$ref: "#/definitions/error_response"
+ /stats:
+ get:
+ operationId: "get_stats"
+ parameters:
+ - name: more
+ in: query
+ type: string
+ required: false
+ responses:
+ 200:
+ description: Success
+ schema:
+ $ref: "#/definitions/stats_response"
+ default:
+ description: Generic Error
+ schema:
+ $ref: "#/definitions/error_response"
diff --git a/rust/fatcat-api/api/swagger.yaml b/rust/fatcat-api/api/swagger.yaml
index d34061fe..3740cbb2 100644
--- a/rust/fatcat-api/api/swagger.yaml
+++ b/rust/fatcat-api/api/swagger.yaml
@@ -1480,6 +1480,40 @@ paths:
path: "/editgroup/:id/accept"
HttpMethod: "Post"
httpmethod: "post"
+ /stats:
+ get:
+ operationId: "get_stats"
+ parameters:
+ - name: "more"
+ in: "query"
+ required: false
+ type: "string"
+ formatString: "{:?}"
+ example: "Some(\"more_example\".to_string())"
+ responses:
+ 200:
+ description: "Success"
+ schema:
+ $ref: "#/definitions/stats_response"
+ x-responseId: "Success"
+ x-uppercaseResponseId: "SUCCESS"
+ uppercase_operation_id: "GET_STATS"
+ uppercase_data_type: "STATSRESPONSE"
+ producesJson: true
+ default:
+ description: "Generic Error"
+ schema:
+ $ref: "#/definitions/error_response"
+ x-responseId: "GenericError"
+ x-uppercaseResponseId: "GENERIC_ERROR"
+ uppercase_operation_id: "GET_STATS"
+ uppercase_data_type: "ERRORRESPONSE"
+ producesJson: true
+ operation_id: "get_stats"
+ uppercase_operation_id: "GET_STATS"
+ path: "/stats"
+ HttpMethod: "Get"
+ httpmethod: "get"
definitions:
error_response:
type: "object"
@@ -2016,6 +2050,14 @@ definitions:
index: 1
raw: "raw"
upperCaseName: "RELEASE_CONTRIB"
+ stats_response:
+ type: "object"
+ properties:
+ extra:
+ type: "object"
+ example:
+ extra: "{}"
+ upperCaseName: "STATS_RESPONSE"
editgroup_edits:
properties:
containers:
diff --git a/rust/fatcat-api/examples/client.rs b/rust/fatcat-api/examples/client.rs
index cf53eb75..28fac094 100644
--- a/rust/fatcat-api/examples/client.rs
+++ b/rust/fatcat-api/examples/client.rs
@@ -14,7 +14,7 @@ use clap::{App, Arg};
use fatcat::{AcceptEditgroupResponse, ApiError, ApiNoContext, ContextWrapperExt, CreateContainerBatchResponse, CreateContainerResponse, CreateCreatorBatchResponse, CreateCreatorResponse,
CreateEditgroupResponse, CreateFileBatchResponse, CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse,
GetContainerResponse, GetCreatorReleasesResponse, GetCreatorResponse, GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse,
- GetReleaseResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse};
+ GetReleaseResponse, GetStatsResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse};
#[allow(unused_imports)]
use futures::{future, stream, Future, Stream};
@@ -39,6 +39,7 @@ fn main() {
"GetFile",
"GetRelease",
"GetReleaseFiles",
+ "GetStats",
"GetWork",
"GetWorkReleases",
"LookupContainer",
@@ -179,6 +180,11 @@ fn main() {
println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>")));
}
+ Some("GetStats") => {
+ let result = client.get_stats(Some("more_example".to_string())).wait();
+ println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>")));
+ }
+
Some("GetWork") => {
let result = client.get_work("id_example".to_string()).wait();
println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>")));
diff --git a/rust/fatcat-api/examples/server_lib/server.rs b/rust/fatcat-api/examples/server_lib/server.rs
index 9ce8b5ff..5f4d7acb 100644
--- a/rust/fatcat-api/examples/server_lib/server.rs
+++ b/rust/fatcat-api/examples/server_lib/server.rs
@@ -13,7 +13,7 @@ use fatcat::models;
use fatcat::{AcceptEditgroupResponse, Api, ApiError, Context, CreateContainerBatchResponse, CreateContainerResponse, CreateCreatorBatchResponse, CreateCreatorResponse, CreateEditgroupResponse,
CreateFileBatchResponse, CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerResponse,
GetCreatorReleasesResponse, GetCreatorResponse, GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse,
- GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse};
+ GetStatsResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse};
#[derive(Copy, Clone)]
pub struct Server;
@@ -149,6 +149,12 @@ impl Api for Server {
Box::new(futures::failed("Generic failure".into()))
}
+ fn get_stats(&self, more: Option<String>, context: &Context) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send> {
+ let context = context.clone();
+ println!("get_stats({:?}) - X-Span-ID: {:?}", more, context.x_span_id.unwrap_or(String::from("<none>")).clone());
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
fn get_work(&self, id: String, context: &Context) -> Box<Future<Item = GetWorkResponse, Error = ApiError> + Send> {
let context = context.clone();
println!("get_work(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone());
diff --git a/rust/fatcat-api/src/client.rs b/rust/fatcat-api/src/client.rs
index c5c4a320..809fd1d6 100644
--- a/rust/fatcat-api/src/client.rs
+++ b/rust/fatcat-api/src/client.rs
@@ -36,7 +36,7 @@ use swagger::{ApiError, Context, XSpanId};
use models;
use {AcceptEditgroupResponse, Api, CreateContainerBatchResponse, CreateContainerResponse, CreateCreatorBatchResponse, CreateCreatorResponse, CreateEditgroupResponse, CreateFileBatchResponse,
CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerResponse, GetCreatorReleasesResponse, GetCreatorResponse,
- GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse, GetWorkReleasesResponse, GetWorkResponse,
+ GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse, GetStatsResponse, GetWorkReleasesResponse, GetWorkResponse,
LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse};
/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes.
@@ -1464,6 +1464,55 @@ impl Api for Client {
Box::new(futures::done(result))
}
+ fn get_stats(&self, param_more: Option<String>, context: &Context) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send> {
+ // Query parameters
+ let query_more = param_more.map_or_else(String::new, |query| format!("more={more}&", more = query.to_string()));
+
+ let url = format!("{}/v0/stats?{more}", self.base_path, more = utf8_percent_encode(&query_more, QUERY_ENCODE_SET));
+
+ let hyper_client = (self.hyper_client)();
+ let request = hyper_client.request(hyper::method::Method::Get, &url);
+ let mut custom_headers = hyper::header::Headers::new();
+
+ context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone())));
+
+ let request = request.headers(custom_headers);
+
+ // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists).
+ fn parse_response(mut response: hyper::client::response::Response) -> Result<GetStatsResponse, ApiError> {
+ match response.status.to_u16() {
+ 200 => {
+ let mut buf = String::new();
+ response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
+ let body = serde_json::from_str::<models::StatsResponse>(&buf)?;
+
+ Ok(GetStatsResponse::Success(body))
+ }
+ 0 => {
+ let mut buf = String::new();
+ response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
+ let body = serde_json::from_str::<models::ErrorResponse>(&buf)?;
+
+ Ok(GetStatsResponse::GenericError(body))
+ }
+ code => {
+ let mut buf = [0; 100];
+ let debug_body = match response.read(&mut buf) {
+ Ok(len) => match str::from_utf8(&buf[..len]) {
+ Ok(body) => Cow::from(body),
+ Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())),
+ },
+ Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
+ };
+ Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", code, response.headers, debug_body)))
+ }
+ }
+ }
+
+ let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response);
+ Box::new(futures::done(result))
+ }
+
fn get_work(&self, param_id: String, context: &Context) -> Box<Future<Item = GetWorkResponse, Error = ApiError> + Send> {
let url = format!("{}/v0/work/{id}", self.base_path, id = utf8_percent_encode(&param_id.to_string(), PATH_SEGMENT_ENCODE_SET));
diff --git a/rust/fatcat-api/src/lib.rs b/rust/fatcat-api/src/lib.rs
index c926966e..fd0cfe54 100644
--- a/rust/fatcat-api/src/lib.rs
+++ b/rust/fatcat-api/src/lib.rs
@@ -279,6 +279,14 @@ pub enum GetReleaseFilesResponse {
}
#[derive(Debug, PartialEq)]
+pub enum GetStatsResponse {
+ /// Success
+ Success(models::StatsResponse),
+ /// Generic Error
+ GenericError(models::ErrorResponse),
+}
+
+#[derive(Debug, PartialEq)]
pub enum GetWorkResponse {
/// Found Entity
FoundEntity(models::WorkEntity),
@@ -394,6 +402,8 @@ pub trait Api {
fn get_release_files(&self, id: String, context: &Context) -> Box<Future<Item = GetReleaseFilesResponse, Error = ApiError> + Send>;
+ fn get_stats(&self, more: Option<String>, context: &Context) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send>;
+
fn get_work(&self, id: String, context: &Context) -> Box<Future<Item = GetWorkResponse, Error = ApiError> + Send>;
fn get_work_releases(&self, id: String, context: &Context) -> Box<Future<Item = GetWorkReleasesResponse, Error = ApiError> + Send>;
@@ -451,6 +461,8 @@ pub trait ApiNoContext {
fn get_release_files(&self, id: String) -> Box<Future<Item = GetReleaseFilesResponse, Error = ApiError> + Send>;
+ fn get_stats(&self, more: Option<String>) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send>;
+
fn get_work(&self, id: String) -> Box<Future<Item = GetWorkResponse, Error = ApiError> + Send>;
fn get_work_releases(&self, id: String) -> Box<Future<Item = GetWorkReleasesResponse, Error = ApiError> + Send>;
@@ -564,6 +576,10 @@ impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> {
self.api().get_release_files(id, &self.context())
}
+ fn get_stats(&self, more: Option<String>) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send> {
+ self.api().get_stats(more, &self.context())
+ }
+
fn get_work(&self, id: String) -> Box<Future<Item = GetWorkResponse, Error = ApiError> + Send> {
self.api().get_work(id, &self.context())
}
diff --git a/rust/fatcat-api/src/mimetypes.rs b/rust/fatcat-api/src/mimetypes.rs
index 68e5ec04..be7e792f 100644
--- a/rust/fatcat-api/src/mimetypes.rs
+++ b/rust/fatcat-api/src/mimetypes.rs
@@ -328,6 +328,14 @@ pub mod responses {
lazy_static! {
pub static ref GET_RELEASE_FILES_GENERIC_ERROR: Mime = mime!(Application / Json);
}
+ /// Create Mime objects for the response content types for GetStats
+ lazy_static! {
+ pub static ref GET_STATS_SUCCESS: Mime = mime!(Application / Json);
+ }
+ /// Create Mime objects for the response content types for GetStats
+ lazy_static! {
+ pub static ref GET_STATS_GENERIC_ERROR: Mime = mime!(Application / Json);
+ }
/// Create Mime objects for the response content types for GetWork
lazy_static! {
pub static ref GET_WORK_FOUND_ENTITY: Mime = mime!(Application / Json);
diff --git a/rust/fatcat-api/src/models.rs b/rust/fatcat-api/src/models.rs
index 140e0c2e..15247ce6 100644
--- a/rust/fatcat-api/src/models.rs
+++ b/rust/fatcat-api/src/models.rs
@@ -618,6 +618,19 @@ impl ReleaseRef {
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct StatsResponse {
+ #[serde(rename = "extra")]
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub extra: Option<serde_json::Value>,
+}
+
+impl StatsResponse {
+ pub fn new() -> StatsResponse {
+ StatsResponse { extra: None }
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Success {
#[serde(rename = "message")]
pub message: String,
diff --git a/rust/fatcat-api/src/server.rs b/rust/fatcat-api/src/server.rs
index 2716dfc5..7eb73122 100644
--- a/rust/fatcat-api/src/server.rs
+++ b/rust/fatcat-api/src/server.rs
@@ -38,7 +38,7 @@ use swagger::{ApiError, Context, XSpanId};
use models;
use {AcceptEditgroupResponse, Api, CreateContainerBatchResponse, CreateContainerResponse, CreateCreatorBatchResponse, CreateCreatorResponse, CreateEditgroupResponse, CreateFileBatchResponse,
CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerResponse, GetCreatorReleasesResponse, GetCreatorResponse,
- GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse, GetWorkReleasesResponse, GetWorkResponse,
+ GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse, GetStatsResponse, GetWorkReleasesResponse, GetWorkResponse,
LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse};
header! { (Warning, "Warning") => [String] }
@@ -2101,6 +2101,64 @@ where
let api_clone = api.clone();
router.get(
+ "/v0/stats",
+ move |req: &mut Request| {
+ let mut context = Context::default();
+
+ // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists).
+ fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response>
+ where
+ T: Api,
+ {
+ context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()));
+ context.auth_data = req.extensions.remove::<AuthData>();
+ context.authorization = req.extensions.remove::<Authorization>();
+
+ // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
+ let query_params = req.get::<UrlEncodedQuery>().unwrap_or_default();
+ let param_more = query_params.get("more").and_then(|list| list.first()).and_then(|x| x.parse::<String>().ok());
+
+ match api.get_stats(param_more, context).wait() {
+ Ok(rsp) => match rsp {
+ GetStatsResponse::Success(body) => {
+ let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize");
+
+ let mut response = Response::with((status::Status::from_u16(200), body_string));
+ response.headers.set(ContentType(mimetypes::responses::GET_STATS_SUCCESS.clone()));
+
+ context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone())));
+
+ Ok(response)
+ }
+ GetStatsResponse::GenericError(body) => {
+ let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize");
+
+ let mut response = Response::with((status::Status::from_u16(0), body_string));
+ response.headers.set(ContentType(mimetypes::responses::GET_STATS_GENERIC_ERROR.clone()));
+
+ context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone())));
+
+ Ok(response)
+ }
+ },
+ Err(_) => {
+ // Application code returned an error. This should not happen, as the implementation should
+ // return a valid response.
+ Err(Response::with((status::InternalServerError, "An internal error occurred".to_string())))
+ }
+ }
+ }
+
+ handle_request(req, &api_clone, &mut context).or_else(|mut response| {
+ context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone())));
+ Ok(response)
+ })
+ },
+ "GetStats",
+ );
+
+ let api_clone = api.clone();
+ router.get(
"/v0/work/:id",
move |req: &mut Request| {
let mut context = Context::default();
diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs
index 44f266a4..7c84ad81 100644
--- a/rust/src/api_server.rs
+++ b/rust/src/api_server.rs
@@ -114,6 +114,17 @@ macro_rules! wrap_lookup_handler {
}
}
+macro_rules! count_entity {
+ ($table:ident, $conn:expr) => {{
+ let count: i64 = $table::table
+ .filter($table::is_live.eq(true))
+ .filter($table::redirect_id.is_null())
+ .select(diesel::dsl::count($table::id))
+ .first($conn)?;
+ count
+ }};
+}
+
#[derive(Clone)]
pub struct Server {
pub db_pool: ConnectionPool,
@@ -363,7 +374,8 @@ impl Server {
.load(&conn)?;
rows.into_iter()
- .map(|(rev, ident, _)| release_row2entity(Some(ident), rev, &conn)).collect()
+ .map(|(rev, ident, _)| release_row2entity(Some(ident), rev, &conn))
+ .collect()
}
fn get_file_handler(&self, id: String) -> Result<FileEntity> {
@@ -429,7 +441,8 @@ impl Server {
.load(&conn)?;
rows.into_iter()
- .map(|(rev, ident, _)| file_row2entity(Some(ident), rev, &conn)).collect()
+ .map(|(rev, ident, _)| file_row2entity(Some(ident), rev, &conn))
+ .collect()
}
fn get_work_handler(&self, id: String) -> Result<WorkEntity> {
@@ -456,7 +469,8 @@ impl Server {
.load(&conn)?;
rows.into_iter()
- .map(|(rev, ident)| release_row2entity(Some(ident), rev, &conn)).collect()
+ .map(|(rev, ident)| release_row2entity(Some(ident), rev, &conn))
+ .collect()
}
fn create_container_handler(
@@ -875,6 +889,31 @@ impl Server {
.collect();
Ok(entries)
}
+
+ fn get_stats_handler(&self, _more: Option<String>) -> Result<StatsResponse> {
+ let conn = self.db_pool.get().expect("db_pool error");
+
+ let merged_editgroups: i64 = changelog::table
+ .select(diesel::dsl::count(changelog::id))
+ .first(&conn)?;
+
+ let val = json!({
+ "entity_counts": {
+ "container": count_entity!(container_ident, &conn),
+ "creator": count_entity!(creator_ident, &conn),
+ "file": count_entity!(file_ident, &conn),
+ "release": count_entity!(release_ident, &conn),
+ "work": count_entity!(work_ident, &conn),
+ },
+ "merged_editgroups": merged_editgroups,
+ // TODO: "release_with_file": ,
+ // TODO: "release_with_doi": ,
+ // TODO: "creator_with_orcid": ,
+ // TODO: "files_with_release": ,
+ // TODO: "container_with_issnl": ,
+ });
+ Ok(StatsResponse { extra: Some(val) })
+ }
}
impl Api for Server {
@@ -1089,4 +1128,18 @@ impl Api for Server {
};
Box::new(futures::done(Ok(ret)))
}
+
+ fn get_stats(
+ &self,
+ more: Option<String>,
+ _context: &Context,
+ ) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send> {
+ let ret = match self.get_stats_handler(more.clone()) {
+ Ok(stats) => GetStatsResponse::Success(stats),
+ Err(e) => GetStatsResponse::GenericError(ErrorResponse {
+ message: e.to_string(),
+ }),
+ };
+ Box::new(futures::done(Ok(ret)))
+ }
}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 8ec850c5..8334b3a5 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -12,6 +12,7 @@ extern crate hyper;
#[macro_use]
extern crate error_chain;
extern crate iron;
+#[macro_use]
extern crate serde_json;
pub mod api_helpers;
@@ -27,6 +28,7 @@ mod errors {
R2d2(::diesel::r2d2::Error);
Uuid(::uuid::ParseError);
Io(::std::io::Error) #[cfg(unix)];
+ Serde(::serde_json::Error);
}
}
}
diff --git a/rust/tests/test_api_server.rs b/rust/tests/test_api_server.rs
index 05dd493f..b8f8b3c4 100644
--- a/rust/tests/test_api_server.rs
+++ b/rust/tests/test_api_server.rs
@@ -429,3 +429,14 @@ fn test_accept_editgroup() {
.unwrap();
assert_eq!(c, 1);
}
+
+#[test]
+fn test_stats() {
+ let (headers, router, _conn) = setup();
+
+ check_response(
+ request::get("http://localhost:9411/v0/stats", headers, &router),
+ status::Ok,
+ Some("merged_editgroups"),
+ );
+}