Skip to main content

doxa_docs/
handler_ops.rs

1//! [`ApidocHandlerOps`] — per-handler hook for mutating the
2//! [`utoipa::openapi::path::Operation`] generated by `#[utoipa::path]`
3//! after it lands in a [`utoipa::openapi::path::Paths`] map.
4//!
5//! Sister trait to [`crate::ApidocHandlerSchemas`]: the method macro
6//! emits an impl on the per-handler `__path_<fn>` struct that walks
7//! every argument type through autoref-specialized
8//! [`crate::__private::OpSecurityContribution`] probes. Argument
9//! types that implement [`crate::DocOperationSecurity`] mutate the
10//! operation in place; types that don't silently no-op.
11//!
12//! The extended [`crate::routes!`] macro calls
13//! [`ApidocHandlerOps::augment`] for every handler so the
14//! contributions land before the [`utoipa_axum::router::OpenApiRouter`]
15//! merges the handler's [`utoipa::openapi::path::Paths`] into the
16//! global document.
17
18use utoipa::openapi::path::{HttpMethod, Operation, PathItem, Paths};
19
20/// Per-handler hook that mutates the [`Operation`] generated by
21/// `#[utoipa::path]` for this handler. Implemented by the method
22/// macro on the same `__path_<fn>` struct that carries the `utoipa`
23/// path metadata; the impl iterates every handler argument through
24/// the [`crate::DocOperationSecurity`] probe.
25///
26/// Called by the extended [`crate::routes!`] macro on the
27/// [`Paths`] returned from `utoipa_axum::routes!()` before merging
28/// into the router. Idempotent — calling [`Self::augment`] twice on
29/// the same paths leaves the operation unchanged.
30pub trait ApidocHandlerOps {
31    /// Apply per-operation augmentations to the operation(s) this
32    /// handler owns inside `paths`. Implementations match on
33    /// `<Self as utoipa::Path>::path()` and
34    /// `<Self as utoipa::Path>::methods()` to pick out the relevant
35    /// operation(s); no-op when no matching operation is present.
36    fn augment(paths: &mut Paths);
37}
38
39/// Find the operation slot on a [`PathItem`] for a given
40/// [`HttpMethod`]. Used by the method-macro-generated
41/// [`ApidocHandlerOps`] impl to pick out the operation matching the
42/// handler's declared methods.
43pub fn operation_for_method_mut(item: &mut PathItem, method: HttpMethod) -> Option<&mut Operation> {
44    match method {
45        HttpMethod::Get => item.get.as_mut(),
46        HttpMethod::Put => item.put.as_mut(),
47        HttpMethod::Post => item.post.as_mut(),
48        HttpMethod::Delete => item.delete.as_mut(),
49        HttpMethod::Options => item.options.as_mut(),
50        HttpMethod::Head => item.head.as_mut(),
51        HttpMethod::Patch => item.patch.as_mut(),
52        HttpMethod::Trace => item.trace.as_mut(),
53    }
54}