diff --git a/server/svix-server/src/lib.rs b/server/svix-server/src/lib.rs index a2778ab58..24fca481e 100644 --- a/server/svix-server/src/lib.rs +++ b/server/svix-server/src/lib.rs @@ -156,7 +156,7 @@ pub async fn run_with_prefix( .nest_api_service("/api/v1", v1_router) .finish_api(&mut openapi); - let openapi = openapi::postprocess_spec(openapi); + openapi::postprocess_spec(&mut openapi); let docs_router = docs::router(openapi); let app = app.merge(docs_router).layer(( layer_fn(move |service| IdempotencyService { diff --git a/server/svix-server/src/main.rs b/server/svix-server/src/main.rs index 6d2af5475..e199f859b 100644 --- a/server/svix-server/src/main.rs +++ b/server/svix-server/src/main.rs @@ -189,7 +189,7 @@ async fn main() -> anyhow::Result<()> { .nest("/api/v1", router) .finish_api(&mut openapi); - let openapi = svix_server::openapi::postprocess_spec(openapi); + svix_server::openapi::postprocess_spec(&mut openapi); println!( "{}", serde_json::to_string_pretty(&openapi).expect("Failed to serialize JSON spec") diff --git a/server/svix-server/src/openapi.rs b/server/svix-server/src/openapi.rs index 86dc822b2..511c2d2ae 100644 --- a/server/svix-server/src/openapi.rs +++ b/server/svix-server/src/openapi.rs @@ -101,7 +101,7 @@ pub fn initialize_openapi() -> OpenApi { /// Replaces OpenAPI 3.1 style `"foo": true` schemas with OpenAPI 3.0 style /// `"foo": {"type": "object"}` schemas. -fn replace_true_schemas(mut openapi: OpenApi) -> OpenApi { +fn replace_true_schemas(openapi: &mut OpenApi) { use schemars::schema::{InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec}; // Checks if it's a plain boolean schema, and if yes replaces it with a @@ -140,24 +140,22 @@ fn replace_true_schemas(mut openapi: OpenApi) -> OpenApi { fn visit_object_validation(obj: &mut Box) { if let Some(additional_props) = &mut obj.additional_properties { - visit_schema(additional_props.as_mut()) + visit_schema(additional_props) } - for (_, schema) in obj.properties.iter_mut() { + for (_, schema) in &mut obj.properties { visit_schema(schema) } } - if let Some(ref mut components) = openapi.components { - for (_, schema) in components.schemas.iter_mut() { + if let Some(components) = &mut openapi.components { + for (_, schema) in &mut components.schemas { visit_schema(&mut schema.json_schema) } } - - openapi } /// Adds the `Idempotency-Key` header parameter to all `POST` operations in the schema. -fn add_idempotency_to_post(mut openapi: OpenApi) -> OpenApi { +fn add_idempotency_to_post(openapi: &mut OpenApi) { // The header's value can be any valid string let string_schema = aide::gen::in_context(|ctx| String::json_schema(&mut ctx.schema)); @@ -179,8 +177,8 @@ fn add_idempotency_to_post(mut openapi: OpenApi) -> OpenApi { extensions: indexmap::indexmap! {}, }; - if let Some(paths) = openapi.paths.as_mut() { - for (_, op) in paths.paths.iter_mut() { + if let Some(paths) = &mut openapi.paths { + for (_, op) in &mut paths.paths { match op { openapi::ReferenceOr::Reference { reference, .. } => { // References to operations should never appear in our @@ -191,55 +189,49 @@ fn add_idempotency_to_post(mut openapi: OpenApi) -> OpenApi { ); } openapi::ReferenceOr::Item(op) => { - if let Some(post) = op.post.as_mut() { + if let Some(post) = &mut op.post { post.parameters.push(ReferenceOr::Item(Parameter::Header { parameter_data: idempotency_key_data.clone(), style: openapi::HeaderStyle::Simple, - })) + })); } } } } } - - openapi } /// Remove schemas from `components.schemas` of the spec which are under normal /// circumstances not referenced. At the moment these are struct schemas used /// by query parameters and path placeholders. -fn remove_unneeded_schemas(mut openapi: OpenApi) -> OpenApi { - if let Some(components) = openapi.components.as_mut() { +fn remove_unneeded_schemas(openapi: &mut OpenApi) { + if let Some(components) = &mut openapi.components { components.schemas.retain(|name, _| { !(name.ends_with("Path") || name.ends_with("QueryParams") || name.starts_with("Pagination")) }); - }; - - openapi + } } /// Replaces the `examples` property of a schema with a singular `example` /// property. /// OpenAPI <=3.0 used `example` as an extension, >=3.1 standardized `examples`. -fn replace_multiple_examples(mut openapi: OpenApi) -> OpenApi { +fn replace_multiple_examples(openapi: &mut OpenApi) { let mut visitor = schemars::visit::SetSingleExample { retain_examples: false, }; - if let Some(components) = openapi.components.as_mut() { - for (_, schema_object) in components.schemas.iter_mut() { + if let Some(components) = &mut openapi.components { + for (_, schema_object) in &mut components.schemas { visitor.visit_schema(&mut schema_object.json_schema); } } - - openapi } /// Applies a list of hacks to the finished OpenAPI spec to make it usable with /// our tooling. -pub fn postprocess_spec(mut openapi: OpenApi) -> OpenApi { +pub fn postprocess_spec(openapi: &mut OpenApi) { let hacks = [ add_idempotency_to_post, remove_unneeded_schemas, @@ -248,10 +240,8 @@ pub fn postprocess_spec(mut openapi: OpenApi) -> OpenApi { ]; for hack in hacks { - openapi = hack(openapi); + hack(openapi); } - - openapi } /// This module documents operational webhooks. To document one define a data