diff options
author | Bryan Newbold <bnewbold@robocracy.org> | 2018-06-30 17:53:28 -0700 |
---|---|---|
committer | Bryan Newbold <bnewbold@robocracy.org> | 2018-06-30 17:57:32 -0700 |
commit | a82cffed703665496913d9ca0155e888ec35716b (patch) | |
tree | d04bb9242e1333fc7e671a645bd97ae528c21459 /rust/fatcat-api/src | |
parent | f4064c19ec140987e15c64e80a3bf0c70025b31b (diff) | |
download | fatcat-a82cffed703665496913d9ca0155e888ec35716b.tar.gz fatcat-a82cffed703665496913d9ca0155e888ec35716b.zip |
add remaining history endpoints
Diffstat (limited to 'rust/fatcat-api/src')
-rw-r--r-- | rust/fatcat-api/src/client.rs | 279 | ||||
-rw-r--r-- | rust/fatcat-api/src/lib.rs | 80 | ||||
-rw-r--r-- | rust/fatcat-api/src/mimetypes.rs | 64 | ||||
-rw-r--r-- | rust/fatcat-api/src/models.rs | 8 | ||||
-rw-r--r-- | rust/fatcat-api/src/server.rs | 375 |
5 files changed, 796 insertions, 10 deletions
diff --git a/rust/fatcat-api/src/client.rs b/rust/fatcat-api/src/client.rs index 02f0e155..54e8b86c 100644 --- a/rust/fatcat-api/src/client.rs +++ b/rust/fatcat-api/src/client.rs @@ -35,9 +35,10 @@ use swagger::{ApiError, Context, XSpanId}; use models; use {AcceptEditgroupResponse, Api, CreateContainerBatchResponse, CreateContainerResponse, CreateCreatorBatchResponse, CreateCreatorResponse, CreateEditgroupResponse, CreateFileBatchResponse, - CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerHistoryResponse, GetContainerResponse, - GetCreatorReleasesResponse, GetCreatorResponse, GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse, - GetStatsResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse}; + CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerHistoryResponse, GetContainerResponse, GetCreatorHistoryResponse, + GetCreatorReleasesResponse, GetCreatorResponse, GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileHistoryResponse, GetFileResponse, GetReleaseFilesResponse, + GetReleaseHistoryResponse, GetReleaseResponse, GetStatsResponse, GetWorkHistoryResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, + LookupFileResponse, LookupReleaseResponse}; /// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. fn into_base_path<T: IntoUrl>(input: T, correct_scheme: Option<&'static str>) -> Result<String, ClientInitError> { @@ -1118,6 +1119,74 @@ impl Api for Client { Box::new(futures::done(result)) } + fn get_creator_history(&self, param_id: String, param_limit: Option<i64>, context: &Context) -> Box<Future<Item = GetCreatorHistoryResponse, Error = ApiError> + Send> { + // Query parameters + let query_limit = param_limit.map_or_else(String::new, |query| format!("limit={limit}&", limit = query.to_string())); + + let url = format!( + "{}/v0/creator/{id}/history?{limit}", + self.base_path, + id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET), + limit = utf8_percent_encode(&query_limit, 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<GetCreatorHistoryResponse, 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::<Vec<models::EntityHistoryEntry>>(&buf)?; + + Ok(GetCreatorHistoryResponse::FoundEntityHistory(body)) + } + 400 => { + 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(GetCreatorHistoryResponse::BadRequest(body)) + } + 404 => { + 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(GetCreatorHistoryResponse::NotFound(body)) + } + 500 => { + 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(GetCreatorHistoryResponse::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_creator_releases(&self, param_id: String, context: &Context) -> Box<Future<Item = GetCreatorReleasesResponse, Error = ApiError> + Send> { let url = format!("{}/v0/creator/{id}/releases", self.base_path, id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET)); @@ -1412,6 +1481,74 @@ impl Api for Client { Box::new(futures::done(result)) } + fn get_file_history(&self, param_id: String, param_limit: Option<i64>, context: &Context) -> Box<Future<Item = GetFileHistoryResponse, Error = ApiError> + Send> { + // Query parameters + let query_limit = param_limit.map_or_else(String::new, |query| format!("limit={limit}&", limit = query.to_string())); + + let url = format!( + "{}/v0/file/{id}/history?{limit}", + self.base_path, + id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET), + limit = utf8_percent_encode(&query_limit, 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<GetFileHistoryResponse, 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::<Vec<models::EntityHistoryEntry>>(&buf)?; + + Ok(GetFileHistoryResponse::FoundEntityHistory(body)) + } + 400 => { + 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(GetFileHistoryResponse::BadRequest(body)) + } + 404 => { + 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(GetFileHistoryResponse::NotFound(body)) + } + 500 => { + 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(GetFileHistoryResponse::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_release(&self, param_id: String, context: &Context) -> Box<Future<Item = GetReleaseResponse, Error = ApiError> + Send> { let url = format!("{}/v0/release/{id}", self.base_path, id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET)); @@ -1532,6 +1669,74 @@ impl Api for Client { Box::new(futures::done(result)) } + fn get_release_history(&self, param_id: String, param_limit: Option<i64>, context: &Context) -> Box<Future<Item = GetReleaseHistoryResponse, Error = ApiError> + Send> { + // Query parameters + let query_limit = param_limit.map_or_else(String::new, |query| format!("limit={limit}&", limit = query.to_string())); + + let url = format!( + "{}/v0/release/{id}/history?{limit}", + self.base_path, + id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET), + limit = utf8_percent_encode(&query_limit, 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<GetReleaseHistoryResponse, 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::<Vec<models::EntityHistoryEntry>>(&buf)?; + + Ok(GetReleaseHistoryResponse::FoundEntityHistory(body)) + } + 400 => { + 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(GetReleaseHistoryResponse::BadRequest(body)) + } + 404 => { + 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(GetReleaseHistoryResponse::NotFound(body)) + } + 500 => { + 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(GetReleaseHistoryResponse::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_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())); @@ -1641,6 +1846,74 @@ impl Api for Client { Box::new(futures::done(result)) } + fn get_work_history(&self, param_id: String, param_limit: Option<i64>, context: &Context) -> Box<Future<Item = GetWorkHistoryResponse, Error = ApiError> + Send> { + // Query parameters + let query_limit = param_limit.map_or_else(String::new, |query| format!("limit={limit}&", limit = query.to_string())); + + let url = format!( + "{}/v0/work/{id}/history?{limit}", + self.base_path, + id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET), + limit = utf8_percent_encode(&query_limit, 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<GetWorkHistoryResponse, 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::<Vec<models::EntityHistoryEntry>>(&buf)?; + + Ok(GetWorkHistoryResponse::FoundEntityHistory(body)) + } + 400 => { + 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(GetWorkHistoryResponse::BadRequest(body)) + } + 404 => { + 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(GetWorkHistoryResponse::NotFound(body)) + } + 500 => { + 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(GetWorkHistoryResponse::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_releases(&self, param_id: String, context: &Context) -> Box<Future<Item = GetWorkReleasesResponse, Error = ApiError> + Send> { let url = format!("{}/v0/work/{id}/releases", self.base_path, id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET)); diff --git a/rust/fatcat-api/src/lib.rs b/rust/fatcat-api/src/lib.rs index 291dcaf4..28636d47 100644 --- a/rust/fatcat-api/src/lib.rs +++ b/rust/fatcat-api/src/lib.rs @@ -211,6 +211,18 @@ pub enum GetCreatorResponse { } #[derive(Debug, PartialEq)] +pub enum GetCreatorHistoryResponse { + /// Found Entity History + FoundEntityHistory(Vec<models::EntityHistoryEntry>), + /// Bad Request + BadRequest(models::ErrorResponse), + /// Not Found + NotFound(models::ErrorResponse), + /// Generic Error + GenericError(models::ErrorResponse), +} + +#[derive(Debug, PartialEq)] pub enum GetCreatorReleasesResponse { /// Found Entity FoundEntity(Vec<models::ReleaseEntity>), @@ -267,6 +279,18 @@ pub enum GetFileResponse { } #[derive(Debug, PartialEq)] +pub enum GetFileHistoryResponse { + /// Found Entity History + FoundEntityHistory(Vec<models::EntityHistoryEntry>), + /// Bad Request + BadRequest(models::ErrorResponse), + /// Not Found + NotFound(models::ErrorResponse), + /// Generic Error + GenericError(models::ErrorResponse), +} + +#[derive(Debug, PartialEq)] pub enum GetReleaseResponse { /// Found Entity FoundEntity(models::ReleaseEntity), @@ -291,6 +315,18 @@ pub enum GetReleaseFilesResponse { } #[derive(Debug, PartialEq)] +pub enum GetReleaseHistoryResponse { + /// Found Entity History + FoundEntityHistory(Vec<models::EntityHistoryEntry>), + /// Bad Request + BadRequest(models::ErrorResponse), + /// Not Found + NotFound(models::ErrorResponse), + /// Generic Error + GenericError(models::ErrorResponse), +} + +#[derive(Debug, PartialEq)] pub enum GetStatsResponse { /// Success Success(models::StatsResponse), @@ -311,6 +347,18 @@ pub enum GetWorkResponse { } #[derive(Debug, PartialEq)] +pub enum GetWorkHistoryResponse { + /// Found Entity History + FoundEntityHistory(Vec<models::EntityHistoryEntry>), + /// Bad Request + BadRequest(models::ErrorResponse), + /// Not Found + NotFound(models::ErrorResponse), + /// Generic Error + GenericError(models::ErrorResponse), +} + +#[derive(Debug, PartialEq)] pub enum GetWorkReleasesResponse { /// Found Entity FoundEntity(Vec<models::ReleaseEntity>), @@ -402,6 +450,8 @@ pub trait Api { fn get_creator(&self, id: String, context: &Context) -> Box<Future<Item = GetCreatorResponse, Error = ApiError> + Send>; + fn get_creator_history(&self, id: String, limit: Option<i64>, context: &Context) -> Box<Future<Item = GetCreatorHistoryResponse, Error = ApiError> + Send>; + fn get_creator_releases(&self, id: String, context: &Context) -> Box<Future<Item = GetCreatorReleasesResponse, Error = ApiError> + Send>; fn get_editgroup(&self, id: i64, context: &Context) -> Box<Future<Item = GetEditgroupResponse, Error = ApiError> + Send>; @@ -412,14 +462,20 @@ pub trait Api { fn get_file(&self, id: String, context: &Context) -> Box<Future<Item = GetFileResponse, Error = ApiError> + Send>; + fn get_file_history(&self, id: String, limit: Option<i64>, context: &Context) -> Box<Future<Item = GetFileHistoryResponse, Error = ApiError> + Send>; + fn get_release(&self, id: String, context: &Context) -> Box<Future<Item = GetReleaseResponse, Error = ApiError> + Send>; fn get_release_files(&self, id: String, context: &Context) -> Box<Future<Item = GetReleaseFilesResponse, Error = ApiError> + Send>; + fn get_release_history(&self, id: String, limit: Option<i64>, context: &Context) -> Box<Future<Item = GetReleaseHistoryResponse, 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_history(&self, id: String, limit: Option<i64>, context: &Context) -> Box<Future<Item = GetWorkHistoryResponse, Error = ApiError> + Send>; + fn get_work_releases(&self, id: String, context: &Context) -> Box<Future<Item = GetWorkReleasesResponse, Error = ApiError> + Send>; fn lookup_container(&self, issnl: String, context: &Context) -> Box<Future<Item = LookupContainerResponse, Error = ApiError> + Send>; @@ -463,6 +519,8 @@ pub trait ApiNoContext { fn get_creator(&self, id: String) -> Box<Future<Item = GetCreatorResponse, Error = ApiError> + Send>; + fn get_creator_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetCreatorHistoryResponse, Error = ApiError> + Send>; + fn get_creator_releases(&self, id: String) -> Box<Future<Item = GetCreatorReleasesResponse, Error = ApiError> + Send>; fn get_editgroup(&self, id: i64) -> Box<Future<Item = GetEditgroupResponse, Error = ApiError> + Send>; @@ -473,14 +531,20 @@ pub trait ApiNoContext { fn get_file(&self, id: String) -> Box<Future<Item = GetFileResponse, Error = ApiError> + Send>; + fn get_file_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetFileHistoryResponse, Error = ApiError> + Send>; + fn get_release(&self, id: String) -> Box<Future<Item = GetReleaseResponse, Error = ApiError> + Send>; fn get_release_files(&self, id: String) -> Box<Future<Item = GetReleaseFilesResponse, Error = ApiError> + Send>; + fn get_release_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetReleaseHistoryResponse, 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_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetWorkHistoryResponse, Error = ApiError> + Send>; + fn get_work_releases(&self, id: String) -> Box<Future<Item = GetWorkReleasesResponse, Error = ApiError> + Send>; fn lookup_container(&self, issnl: String) -> Box<Future<Item = LookupContainerResponse, Error = ApiError> + Send>; @@ -568,6 +632,10 @@ impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { self.api().get_creator(id, &self.context()) } + fn get_creator_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetCreatorHistoryResponse, Error = ApiError> + Send> { + self.api().get_creator_history(id, limit, &self.context()) + } + fn get_creator_releases(&self, id: String) -> Box<Future<Item = GetCreatorReleasesResponse, Error = ApiError> + Send> { self.api().get_creator_releases(id, &self.context()) } @@ -588,6 +656,10 @@ impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { self.api().get_file(id, &self.context()) } + fn get_file_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetFileHistoryResponse, Error = ApiError> + Send> { + self.api().get_file_history(id, limit, &self.context()) + } + fn get_release(&self, id: String) -> Box<Future<Item = GetReleaseResponse, Error = ApiError> + Send> { self.api().get_release(id, &self.context()) } @@ -596,6 +668,10 @@ impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { self.api().get_release_files(id, &self.context()) } + fn get_release_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetReleaseHistoryResponse, Error = ApiError> + Send> { + self.api().get_release_history(id, limit, &self.context()) + } + fn get_stats(&self, more: Option<String>) -> Box<Future<Item = GetStatsResponse, Error = ApiError> + Send> { self.api().get_stats(more, &self.context()) } @@ -604,6 +680,10 @@ impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { self.api().get_work(id, &self.context()) } + fn get_work_history(&self, id: String, limit: Option<i64>) -> Box<Future<Item = GetWorkHistoryResponse, Error = ApiError> + Send> { + self.api().get_work_history(id, limit, &self.context()) + } + fn get_work_releases(&self, id: String) -> Box<Future<Item = GetWorkReleasesResponse, Error = ApiError> + Send> { self.api().get_work_releases(id, &self.context()) } diff --git a/rust/fatcat-api/src/mimetypes.rs b/rust/fatcat-api/src/mimetypes.rs index 0384b319..8d67551a 100644 --- a/rust/fatcat-api/src/mimetypes.rs +++ b/rust/fatcat-api/src/mimetypes.rs @@ -240,6 +240,22 @@ pub mod responses { lazy_static! { pub static ref GET_CREATOR_GENERIC_ERROR: Mime = mime!(Application / Json); } + /// Create Mime objects for the response content types for GetCreatorHistory + lazy_static! { + pub static ref GET_CREATOR_HISTORY_FOUND_ENTITY_HISTORY: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetCreatorHistory + lazy_static! { + pub static ref GET_CREATOR_HISTORY_BAD_REQUEST: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetCreatorHistory + lazy_static! { + pub static ref GET_CREATOR_HISTORY_NOT_FOUND: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetCreatorHistory + lazy_static! { + pub static ref GET_CREATOR_HISTORY_GENERIC_ERROR: Mime = mime!(Application / Json); + } /// Create Mime objects for the response content types for GetCreatorReleases lazy_static! { pub static ref GET_CREATOR_RELEASES_FOUND_ENTITY: Mime = mime!(Application / Json); @@ -312,6 +328,22 @@ pub mod responses { lazy_static! { pub static ref GET_FILE_GENERIC_ERROR: Mime = mime!(Application / Json); } + /// Create Mime objects for the response content types for GetFileHistory + lazy_static! { + pub static ref GET_FILE_HISTORY_FOUND_ENTITY_HISTORY: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetFileHistory + lazy_static! { + pub static ref GET_FILE_HISTORY_BAD_REQUEST: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetFileHistory + lazy_static! { + pub static ref GET_FILE_HISTORY_NOT_FOUND: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetFileHistory + lazy_static! { + pub static ref GET_FILE_HISTORY_GENERIC_ERROR: Mime = mime!(Application / Json); + } /// Create Mime objects for the response content types for GetRelease lazy_static! { pub static ref GET_RELEASE_FOUND_ENTITY: Mime = mime!(Application / Json); @@ -344,6 +376,22 @@ 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 GetReleaseHistory + lazy_static! { + pub static ref GET_RELEASE_HISTORY_FOUND_ENTITY_HISTORY: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetReleaseHistory + lazy_static! { + pub static ref GET_RELEASE_HISTORY_BAD_REQUEST: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetReleaseHistory + lazy_static! { + pub static ref GET_RELEASE_HISTORY_NOT_FOUND: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetReleaseHistory + lazy_static! { + pub static ref GET_RELEASE_HISTORY_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); @@ -368,6 +416,22 @@ pub mod responses { lazy_static! { pub static ref GET_WORK_GENERIC_ERROR: Mime = mime!(Application / Json); } + /// Create Mime objects for the response content types for GetWorkHistory + lazy_static! { + pub static ref GET_WORK_HISTORY_FOUND_ENTITY_HISTORY: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetWorkHistory + lazy_static! { + pub static ref GET_WORK_HISTORY_BAD_REQUEST: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetWorkHistory + lazy_static! { + pub static ref GET_WORK_HISTORY_NOT_FOUND: Mime = mime!(Application / Json); + } + /// Create Mime objects for the response content types for GetWorkHistory + lazy_static! { + pub static ref GET_WORK_HISTORY_GENERIC_ERROR: Mime = mime!(Application / Json); + } /// Create Mime objects for the response content types for GetWorkReleases lazy_static! { pub static ref GET_WORK_RELEASES_FOUND_ENTITY: Mime = mime!(Application / Json); diff --git a/rust/fatcat-api/src/models.rs b/rust/fatcat-api/src/models.rs index f33ed9db..94edf5c0 100644 --- a/rust/fatcat-api/src/models.rs +++ b/rust/fatcat-api/src/models.rs @@ -282,16 +282,16 @@ pub struct EntityHistoryEntry { #[serde(rename = "editgroup")] pub editgroup: models::Editgroup, - #[serde(rename = "changelog")] - pub changelog: models::ChangelogEntry, + #[serde(rename = "changelog_entry")] + pub changelog_entry: models::ChangelogEntry, } impl EntityHistoryEntry { - pub fn new(edit: models::EntityEdit, editgroup: models::Editgroup, changelog: models::ChangelogEntry) -> EntityHistoryEntry { + pub fn new(edit: models::EntityEdit, editgroup: models::Editgroup, changelog_entry: models::ChangelogEntry) -> EntityHistoryEntry { EntityHistoryEntry { edit: edit, editgroup: editgroup, - changelog: changelog, + changelog_entry: changelog_entry, } } } diff --git a/rust/fatcat-api/src/server.rs b/rust/fatcat-api/src/server.rs index f01dde1b..e881b313 100644 --- a/rust/fatcat-api/src/server.rs +++ b/rust/fatcat-api/src/server.rs @@ -37,9 +37,10 @@ use swagger::{ApiError, Context, XSpanId}; #[allow(unused_imports)] use models; use {AcceptEditgroupResponse, Api, CreateContainerBatchResponse, CreateContainerResponse, CreateCreatorBatchResponse, CreateCreatorResponse, CreateEditgroupResponse, CreateFileBatchResponse, - CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerHistoryResponse, GetContainerResponse, - GetCreatorReleasesResponse, GetCreatorResponse, GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileResponse, GetReleaseFilesResponse, GetReleaseResponse, - GetStatsResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse}; + CreateFileResponse, CreateReleaseBatchResponse, CreateReleaseResponse, CreateWorkBatchResponse, CreateWorkResponse, GetContainerHistoryResponse, GetContainerResponse, GetCreatorHistoryResponse, + GetCreatorReleasesResponse, GetCreatorResponse, GetEditgroupResponse, GetEditorChangelogResponse, GetEditorResponse, GetFileHistoryResponse, GetFileResponse, GetReleaseFilesResponse, + GetReleaseHistoryResponse, GetReleaseResponse, GetStatsResponse, GetWorkHistoryResponse, GetWorkReleasesResponse, GetWorkResponse, LookupContainerResponse, LookupCreatorResponse, + LookupFileResponse, LookupReleaseResponse}; header! { (Warning, "Warning") => [String] } @@ -1597,6 +1598,98 @@ where let api_clone = api.clone(); router.get( + "/v0/creator/:id/history", + 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>(); + + // Path parameters + let param_id = { + let param = req.extensions + .get::<Router>() + .ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id") + .ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()) + .decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse() + .map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + // 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_limit = query_params.get("limit").and_then(|list| list.first()).and_then(|x| x.parse::<i64>().ok()); + + match api.get_creator_history(param_id, param_limit, context).wait() { + Ok(rsp) => match rsp { + GetCreatorHistoryResponse::FoundEntityHistory(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_CREATOR_HISTORY_FOUND_ENTITY_HISTORY.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetCreatorHistoryResponse::BadRequest(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_CREATOR_HISTORY_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetCreatorHistoryResponse::NotFound(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_CREATOR_HISTORY_NOT_FOUND.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetCreatorHistoryResponse::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(500), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_CREATOR_HISTORY_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) + }) + }, + "GetCreatorHistory", + ); + + let api_clone = api.clone(); + router.get( "/v0/creator/:id/releases", move |req: &mut Request| { let mut context = Context::default(); @@ -2017,6 +2110,98 @@ where let api_clone = api.clone(); router.get( + "/v0/file/:id/history", + 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>(); + + // Path parameters + let param_id = { + let param = req.extensions + .get::<Router>() + .ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id") + .ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()) + .decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse() + .map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + // 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_limit = query_params.get("limit").and_then(|list| list.first()).and_then(|x| x.parse::<i64>().ok()); + + match api.get_file_history(param_id, param_limit, context).wait() { + Ok(rsp) => match rsp { + GetFileHistoryResponse::FoundEntityHistory(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_FILE_HISTORY_FOUND_ENTITY_HISTORY.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetFileHistoryResponse::BadRequest(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_FILE_HISTORY_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetFileHistoryResponse::NotFound(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_FILE_HISTORY_NOT_FOUND.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetFileHistoryResponse::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(500), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_FILE_HISTORY_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) + }) + }, + "GetFileHistory", + ); + + let api_clone = api.clone(); + router.get( "/v0/release/:id", move |req: &mut Request| { let mut context = Context::default(); @@ -2193,6 +2378,98 @@ where let api_clone = api.clone(); router.get( + "/v0/release/:id/history", + 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>(); + + // Path parameters + let param_id = { + let param = req.extensions + .get::<Router>() + .ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id") + .ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()) + .decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse() + .map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + // 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_limit = query_params.get("limit").and_then(|list| list.first()).and_then(|x| x.parse::<i64>().ok()); + + match api.get_release_history(param_id, param_limit, context).wait() { + Ok(rsp) => match rsp { + GetReleaseHistoryResponse::FoundEntityHistory(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_RELEASE_HISTORY_FOUND_ENTITY_HISTORY.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetReleaseHistoryResponse::BadRequest(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_RELEASE_HISTORY_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetReleaseHistoryResponse::NotFound(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_RELEASE_HISTORY_NOT_FOUND.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetReleaseHistoryResponse::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(500), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_RELEASE_HISTORY_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) + }) + }, + "GetReleaseHistory", + ); + + let api_clone = api.clone(); + router.get( "/v0/stats", move |req: &mut Request| { let mut context = Context::default(); @@ -2339,6 +2616,98 @@ where let api_clone = api.clone(); router.get( + "/v0/work/:id/history", + 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>(); + + // Path parameters + let param_id = { + let param = req.extensions + .get::<Router>() + .ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id") + .ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()) + .decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse() + .map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + // 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_limit = query_params.get("limit").and_then(|list| list.first()).and_then(|x| x.parse::<i64>().ok()); + + match api.get_work_history(param_id, param_limit, context).wait() { + Ok(rsp) => match rsp { + GetWorkHistoryResponse::FoundEntityHistory(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_WORK_HISTORY_FOUND_ENTITY_HISTORY.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetWorkHistoryResponse::BadRequest(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_WORK_HISTORY_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetWorkHistoryResponse::NotFound(body) => { + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_WORK_HISTORY_NOT_FOUND.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + } + GetWorkHistoryResponse::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(500), body_string)); + response.headers.set(ContentType(mimetypes::responses::GET_WORK_HISTORY_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) + }) + }, + "GetWorkHistory", + ); + + let api_clone = api.clone(); + router.get( "/v0/work/:id/releases", move |req: &mut Request| { let mut context = Context::default(); |