diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2019-01-03 17:53:04 -0800 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2019-01-03 17:53:04 -0800 | 
| commit | 65fa084379a159db81fc5424deda18013f01194b (patch) | |
| tree | 6a8563e716c646a75326eda324ce28aaf0ad018d /rust/fatcat-api-spec/src | |
| parent | b10ee85c04816f16738ff30b84262a6ab8440307 (diff) | |
| download | fatcat-65fa084379a159db81fc5424deda18013f01194b.tar.gz fatcat-65fa084379a159db81fc5424deda18013f01194b.zip | |
rust codegen
Diffstat (limited to 'rust/fatcat-api-spec/src')
| -rw-r--r-- | rust/fatcat-api-spec/src/client.rs | 93 | ||||
| -rw-r--r-- | rust/fatcat-api-spec/src/lib.rs | 24 | ||||
| -rw-r--r-- | rust/fatcat-api-spec/src/mimetypes.rs | 28 | ||||
| -rw-r--r-- | rust/fatcat-api-spec/src/server.rs | 153 | 
4 files changed, 296 insertions, 2 deletions
| diff --git a/rust/fatcat-api-spec/src/client.rs b/rust/fatcat-api-spec/src/client.rs index 44bcd54d..470a5350 100644 --- a/rust/fatcat-api-spec/src/client.rs +++ b/rust/fatcat-api-spec/src/client.rs @@ -46,7 +46,7 @@ use {      GetReleaseFilesResponse, GetReleaseFilesetsResponse, GetReleaseHistoryResponse, GetReleaseRedirectsResponse, GetReleaseResponse, GetReleaseRevisionResponse, GetReleaseWebcapturesResponse,      GetWebcaptureEditResponse, GetWebcaptureHistoryResponse, GetWebcaptureRedirectsResponse, GetWebcaptureResponse, GetWebcaptureRevisionResponse, GetWorkEditResponse, GetWorkHistoryResponse,      GetWorkRedirectsResponse, GetWorkReleasesResponse, GetWorkResponse, GetWorkRevisionResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse, -    UpdateContainerResponse, UpdateCreatorResponse, UpdateFileResponse, UpdateFilesetResponse, UpdateReleaseResponse, UpdateWebcaptureResponse, UpdateWorkResponse, +    UpdateContainerResponse, UpdateCreatorResponse, UpdateEditorResponse, UpdateFileResponse, UpdateFilesetResponse, UpdateReleaseResponse, UpdateWebcaptureResponse, UpdateWorkResponse,  };  /// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. @@ -2252,6 +2252,97 @@ impl Api for Client {          Box::new(futures::done(result))      } +    fn update_editor(&self, param_editor_id: String, param_editor: models::Editor, context: &Context) -> Box<Future<Item = UpdateEditorResponse, Error = ApiError> + Send> { +        let url = format!( +            "{}/v0/editor/{editor_id}", +            self.base_path, +            editor_id = utf8_percent_encode(¶m_editor_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let body = serde_json::to_string(¶m_editor).expect("impossible to fail to serialize"); + +        let hyper_client = (self.hyper_client)(); +        let request = hyper_client.request(hyper::method::Method::Put, &url); +        let mut custom_headers = hyper::header::Headers::new(); + +        let request = request.body(&body); + +        custom_headers.set(ContentType(mimetypes::requests::UPDATE_EDITOR.clone())); +        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<UpdateEditorResponse, 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::Editor>(&buf)?; + +                    Ok(UpdateEditorResponse::UpdatedEditor(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(UpdateEditorResponse::BadRequest(body)) +                } +                401 => { +                    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)?; +                    header! { (ResponseWwwAuthenticate, "WWW_Authenticate") => [String] } +                    let response_www_authenticate = response +                        .headers +                        .get::<ResponseWwwAuthenticate>() +                        .ok_or_else(|| "Required response header WWW_Authenticate for response 401 was not found.")?; + +                    Ok(UpdateEditorResponse::NotAuthorized { +                        body: body, +                        www_authenticate: response_www_authenticate.0.clone(), +                    }) +                } +                403 => { +                    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(UpdateEditorResponse::Forbidden(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(UpdateEditorResponse::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(UpdateEditorResponse::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 accept_editgroup(&self, param_editgroup_id: String, context: &Context) -> Box<Future<Item = AcceptEditgroupResponse, Error = ApiError> + Send> {          let url = format!(              "{}/v0/editgroup/{editgroup_id}/accept", diff --git a/rust/fatcat-api-spec/src/lib.rs b/rust/fatcat-api-spec/src/lib.rs index c89dc90c..258b635b 100644 --- a/rust/fatcat-api-spec/src/lib.rs +++ b/rust/fatcat-api-spec/src/lib.rs @@ -391,6 +391,22 @@ pub enum GetEditorChangelogResponse {  }  #[derive(Debug, PartialEq)] +pub enum UpdateEditorResponse { +    /// Updated Editor +    UpdatedEditor(models::Editor), +    /// Bad Request +    BadRequest(models::ErrorResponse), +    /// Not Authorized +    NotAuthorized { body: models::ErrorResponse, www_authenticate: String }, +    /// Forbidden +    Forbidden(models::ErrorResponse), +    /// Not Found +    NotFound(models::ErrorResponse), +    /// Generic Error +    GenericError(models::ErrorResponse), +} + +#[derive(Debug, PartialEq)]  pub enum AcceptEditgroupResponse {      /// Merged Successfully      MergedSuccessfully(models::Success), @@ -1305,6 +1321,8 @@ pub trait Api {      fn get_editor_changelog(&self, editor_id: String, context: &Context) -> Box<Future<Item = GetEditorChangelogResponse, Error = ApiError> + Send>; +    fn update_editor(&self, editor_id: String, editor: models::Editor, context: &Context) -> Box<Future<Item = UpdateEditorResponse, Error = ApiError> + Send>; +      fn accept_editgroup(&self, editgroup_id: String, context: &Context) -> Box<Future<Item = AcceptEditgroupResponse, Error = ApiError> + Send>;      fn create_editgroup(&self, editgroup: models::Editgroup, context: &Context) -> Box<Future<Item = CreateEditgroupResponse, Error = ApiError> + Send>; @@ -1553,6 +1571,8 @@ pub trait ApiNoContext {      fn get_editor_changelog(&self, editor_id: String) -> Box<Future<Item = GetEditorChangelogResponse, Error = ApiError> + Send>; +    fn update_editor(&self, editor_id: String, editor: models::Editor) -> Box<Future<Item = UpdateEditorResponse, Error = ApiError> + Send>; +      fn accept_editgroup(&self, editgroup_id: String) -> Box<Future<Item = AcceptEditgroupResponse, Error = ApiError> + Send>;      fn create_editgroup(&self, editgroup: models::Editgroup) -> Box<Future<Item = CreateEditgroupResponse, Error = ApiError> + Send>; @@ -1844,6 +1864,10 @@ impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> {          self.api().get_editor_changelog(editor_id, &self.context())      } +    fn update_editor(&self, editor_id: String, editor: models::Editor) -> Box<Future<Item = UpdateEditorResponse, Error = ApiError> + Send> { +        self.api().update_editor(editor_id, editor, &self.context()) +    } +      fn accept_editgroup(&self, editgroup_id: String) -> Box<Future<Item = AcceptEditgroupResponse, Error = ApiError> + Send> {          self.api().accept_editgroup(editgroup_id, &self.context())      } diff --git a/rust/fatcat-api-spec/src/mimetypes.rs b/rust/fatcat-api-spec/src/mimetypes.rs index 322ab045..cfdd357d 100644 --- a/rust/fatcat-api-spec/src/mimetypes.rs +++ b/rust/fatcat-api-spec/src/mimetypes.rs @@ -512,6 +512,30 @@ pub mod responses {      lazy_static! {          pub static ref GET_EDITOR_CHANGELOG_GENERIC_ERROR: Mime = mime!(Application / Json);      } +    /// Create Mime objects for the response content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR_UPDATED_EDITOR: Mime = mime!(Application / Json); +    } +    /// Create Mime objects for the response content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR_BAD_REQUEST: Mime = mime!(Application / Json); +    } +    /// Create Mime objects for the response content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR_NOT_AUTHORIZED: Mime = mime!(Application / Json); +    } +    /// Create Mime objects for the response content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR_FORBIDDEN: Mime = mime!(Application / Json); +    } +    /// Create Mime objects for the response content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR_NOT_FOUND: Mime = mime!(Application / Json); +    } +    /// Create Mime objects for the response content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR_GENERIC_ERROR: Mime = mime!(Application / Json); +    }      /// Create Mime objects for the response content types for AcceptEditgroup      lazy_static! {          pub static ref ACCEPT_EDITGROUP_MERGED_SUCCESSFULLY: Mime = mime!(Application / Json); @@ -1725,6 +1749,10 @@ pub mod requests {      lazy_static! {          pub static ref AUTH_OIDC: Mime = mime!(Application / Json);      } +    /// Create Mime objects for the request content types for UpdateEditor +    lazy_static! { +        pub static ref UPDATE_EDITOR: Mime = mime!(Application / Json); +    }      /// Create Mime objects for the request content types for CreateEditgroup      lazy_static! {          pub static ref CREATE_EDITGROUP: Mime = mime!(Application / Json); diff --git a/rust/fatcat-api-spec/src/server.rs b/rust/fatcat-api-spec/src/server.rs index 8a515e43..c0903676 100644 --- a/rust/fatcat-api-spec/src/server.rs +++ b/rust/fatcat-api-spec/src/server.rs @@ -48,7 +48,7 @@ use {      GetReleaseFilesResponse, GetReleaseFilesetsResponse, GetReleaseHistoryResponse, GetReleaseRedirectsResponse, GetReleaseResponse, GetReleaseRevisionResponse, GetReleaseWebcapturesResponse,      GetWebcaptureEditResponse, GetWebcaptureHistoryResponse, GetWebcaptureRedirectsResponse, GetWebcaptureResponse, GetWebcaptureRevisionResponse, GetWorkEditResponse, GetWorkHistoryResponse,      GetWorkRedirectsResponse, GetWorkReleasesResponse, GetWorkResponse, GetWorkRevisionResponse, LookupContainerResponse, LookupCreatorResponse, LookupFileResponse, LookupReleaseResponse, -    UpdateContainerResponse, UpdateCreatorResponse, UpdateFileResponse, UpdateFilesetResponse, UpdateReleaseResponse, UpdateWebcaptureResponse, UpdateWorkResponse, +    UpdateContainerResponse, UpdateCreatorResponse, UpdateEditorResponse, UpdateFileResponse, UpdateFilesetResponse, UpdateReleaseResponse, UpdateWebcaptureResponse, UpdateWorkResponse,  };  header! { (Warning, "Warning") => [String] } @@ -2932,6 +2932,157 @@ where      );      let api_clone = api.clone(); +    router.put( +        "/v0/editor/:editor_id", +        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>(); + +                let authorization = context.authorization.as_ref().ok_or_else(|| Response::with((status::Forbidden, "Unauthenticated".to_string())))?; + +                // Path parameters +                let param_editor_id = { +                    let param = req +                        .extensions +                        .get::<Router>() +                        .ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? +                        .find("editor_id") +                        .ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter editor_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 editor_id: {}", e))))? +                }; + +                // Body parameters (note that non-required body parameters will ignore garbage +                // values, rather than causing a 400 response). Produce warning header and logs for +                // any unused fields. + +                let param_editor = req +                    .get::<bodyparser::Raw>() +                    .map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter editor - not valid UTF-8: {}", e))))?; + +                let mut unused_elements = Vec::new(); + +                let param_editor = if let Some(param_editor_raw) = param_editor { +                    let deserializer = &mut serde_json::Deserializer::from_str(¶m_editor_raw); + +                    let param_editor: Option<models::Editor> = serde_ignored::deserialize(deserializer, |path| { +                        warn!("Ignoring unknown field in body: {}", path); +                        unused_elements.push(path.to_string()); +                    }) +                    .map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter editor - doesn't match schema: {}", e))))?; + +                    param_editor +                } else { +                    None +                }; +                let param_editor = param_editor.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter editor".to_string())))?; + +                match api.update_editor(param_editor_id, param_editor, context).wait() { +                    Ok(rsp) => match rsp { +                        UpdateEditorResponse::UpdatedEditor(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::UPDATE_EDITOR_UPDATED_EDITOR.clone())); + +                            context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); +                            if !unused_elements.is_empty() { +                                response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); +                            } +                            Ok(response) +                        } +                        UpdateEditorResponse::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::UPDATE_EDITOR_BAD_REQUEST.clone())); + +                            context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); +                            if !unused_elements.is_empty() { +                                response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); +                            } +                            Ok(response) +                        } +                        UpdateEditorResponse::NotAuthorized { body, www_authenticate } => { +                            let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                            let mut response = Response::with((status::Status::from_u16(401), body_string)); +                            header! { (ResponseWwwAuthenticate, "WWW_Authenticate") => [String] } +                            response.headers.set(ResponseWwwAuthenticate(www_authenticate)); + +                            response.headers.set(ContentType(mimetypes::responses::UPDATE_EDITOR_NOT_AUTHORIZED.clone())); + +                            context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); +                            if !unused_elements.is_empty() { +                                response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); +                            } +                            Ok(response) +                        } +                        UpdateEditorResponse::Forbidden(body) => { +                            let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                            let mut response = Response::with((status::Status::from_u16(403), body_string)); +                            response.headers.set(ContentType(mimetypes::responses::UPDATE_EDITOR_FORBIDDEN.clone())); + +                            context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); +                            if !unused_elements.is_empty() { +                                response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); +                            } +                            Ok(response) +                        } +                        UpdateEditorResponse::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::UPDATE_EDITOR_NOT_FOUND.clone())); + +                            context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); +                            if !unused_elements.is_empty() { +                                response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); +                            } +                            Ok(response) +                        } +                        UpdateEditorResponse::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::UPDATE_EDITOR_GENERIC_ERROR.clone())); + +                            context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); +                            if !unused_elements.is_empty() { +                                response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); +                            } +                            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) +            }) +        }, +        "UpdateEditor", +    ); + +    let api_clone = api.clone();      router.post(          "/v0/editgroup/:editgroup_id/accept",          move |req: &mut Request| { | 
