openapi_31/v31/
reference.rs

1// OpenAPI v3.1.0 Specification
2//
3// OpenAPI inside OpenAPI
4//
5// The version of the OpenAPI document: 3.1.0
6//
7// Generated by: https://openapi-generator.tech
8
9use std::{default, ops::Deref};
10
11use derive_more::{Display, Error};
12
13use crate::v31;
14
15#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
16pub struct Reference {
17  #[serde(rename = "$ref", skip_serializing_if = "Option::is_none")]
18  pub dollar_ref: Option<String>,
19  #[serde(rename = "summary", skip_serializing_if = "Option::is_none")]
20  pub summary: Option<String>,
21  #[serde(rename = "description", skip_serializing_if = "Option::is_none")]
22  pub description: Option<String>,
23}
24
25impl Reference {
26  pub fn new() -> Reference {
27    Reference { dollar_ref: None, summary: None, description: None }
28  }
29}
30
31#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
32#[serde(untagged)]
33pub enum ObjectOrRef<T> {
34  Object(T),
35  Ref {
36    #[serde(rename = "$ref")]
37    r#ref: String,
38  },
39}
40
41#[derive(Clone, Debug, PartialEq, Display, Error)]
42pub enum ObjectRefErr {
43  #[display(fmt = "unresolved reference")]
44  UnresolvedRef,
45
46  #[display(fmt = "mismatch reference")]
47  MismatchedRef,
48
49  #[display(fmt = "reference error")]
50  Ref,
51}
52
53impl<T> ObjectOrRef<T>
54where
55  T: Resolve + Clone,
56{
57  pub fn resolve(&self, openapi: &v31::Openapi) -> Result<T, ObjectRefErr> {
58    match self {
59      ObjectOrRef::Object(object) => Ok(object.clone()),
60      ObjectOrRef::Ref { r#ref } => T::resolve(r#ref, openapi),
61    }
62  }
63}
64
65pub trait Resolve {
66  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, ObjectRefErr>
67  where
68    Self: Sized;
69}
70
71#[macro_export]
72macro_rules! default_resolve_strategy {
73  ($ref:ident, $openapi:ident, $component:ident, $postfix:literal) => {{
74    static REF_PREFIX: &str = concat!("#/components/", $postfix, "/");
75    if !$ref.starts_with(REF_PREFIX) {
76      return Err(v31::reference::ObjectRefErr::MismatchedRef);
77    }
78    let (_, item_name) = $ref.split_at(REF_PREFIX.len());
79    $openapi
80      .components
81      .as_ref()
82      .and_then(|components| components.$component.as_ref())
83      .and_then(|items| items.get(item_name))
84      .and_then(|item| Some(item.clone()))
85      .ok_or_else(|| v31::reference::ObjectRefErr::UnresolvedRef)
86  }};
87}
88
89impl Resolve for v31::Parameter {
90  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, v31::reference::ObjectRefErr> {
91    default_resolve_strategy!(r#ref, openapi, parameters, "parameters")
92  }
93}
94
95impl Resolve for v31::Response {
96  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, v31::reference::ObjectRefErr> {
97    default_resolve_strategy!(r#ref, openapi, responses, "responses")
98  }
99}
100
101impl Resolve for v31::Examples {
102  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, v31::reference::ObjectRefErr> {
103    default_resolve_strategy!(r#ref, openapi, examples, "examples")
104  }
105}
106
107impl Resolve for v31::RequestBody {
108  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, v31::reference::ObjectRefErr> {
109    default_resolve_strategy!(r#ref, openapi, request_bodies, "requestBodies")
110  }
111}
112
113impl Resolve for v31::Header {
114  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, v31::reference::ObjectRefErr> {
115    default_resolve_strategy!(r#ref, openapi, headers, "headers")
116  }
117}
118
119impl Resolve for v31::SecurityScheme {
120  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, ObjectRefErr> {
121    default_resolve_strategy!(r#ref, openapi, security_schemes, "securitySchemas")
122  }
123}
124
125impl Resolve for v31::Link {
126  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, ObjectRefErr> {
127    default_resolve_strategy!(r#ref, openapi, links, "links")
128  }
129}
130
131impl Resolve for v31::PathItem {
132  fn resolve(r#ref: &str, openapi: &v31::Openapi) -> Result<Self, v31::reference::ObjectRefErr> {
133    default_resolve_strategy!(r#ref, openapi, path_items, "pathItems")
134  }
135}