openapi_nexus_core/traits/
openapi_parameter_ext.rs

1use utoipa::openapi;
2
3use super::openapi_ref_ext::OpenApiRefExt as _;
4
5/// Extension trait for OpenAPI `Parameter` to provide convenience methods.
6pub trait OpenApiParameterExt {
7    /// Returns `true` if the parameter is required.
8    fn required(&self) -> bool;
9
10    /// Returns `true` if the parameter is deprecated.
11    fn deprecated(&self) -> bool;
12
13    /// Extract default value from the parameter's schema.
14    ///
15    /// Returns `None` if the parameter has no schema or no default value is specified.
16    /// For referenced schemas, resolves the reference using the provided `Components`.
17    fn default_value(&self, components: Option<&openapi::Components>) -> Option<serde_json::Value>;
18}
19
20impl OpenApiParameterExt for openapi::path::Parameter {
21    fn required(&self) -> bool {
22        matches!(self.required, openapi::Required::True)
23    }
24
25    fn deprecated(&self) -> bool {
26        matches!(self.deprecated, Some(openapi::Deprecated::True))
27    }
28
29    fn default_value(&self, components: Option<&openapi::Components>) -> Option<serde_json::Value> {
30        let schema_ref = self.schema.as_ref()?;
31        extract_default_value_from_schema(schema_ref, components)
32    }
33}
34
35/// Extract default value from a schema reference (helper for recursive resolution)
36fn extract_default_value_from_schema(
37    schema_ref: &openapi::RefOr<openapi::Schema>,
38    components: Option<&openapi::Components>,
39) -> Option<serde_json::Value> {
40    match (schema_ref, components) {
41        (openapi::RefOr::T(openapi::Schema::Object(obj)), _) => obj.default.clone(),
42        (openapi::RefOr::Ref(reference), Some(components)) => reference
43            .schema_name()
44            .and_then(|schema_name| components.schemas.get(schema_name))
45            .and_then(|resolved_schema| {
46                extract_default_value_from_schema(resolved_schema, Some(components))
47            }),
48        _ => None,
49    }
50}