Skip to main content

openapiv3_resolve/resolved/
parameter.rs

1use super::resolver::{Resolvable, Resolver};
2use super::{ResolvedMediaType, ResolvedSchema, Shared};
3use crate::ResolveError;
4use indexmap::IndexMap;
5use openapiv3::{
6    CookieStyle, Example, Header, HeaderStyle, Parameter, ParameterData, ParameterSchemaOrContent,
7    PathStyle, QueryStyle,
8};
9
10/// [`Parameter`] with every `$ref` replaced by the item it named.
11#[derive(Debug, PartialEq)]
12pub enum ResolvedParameter {
13    /// See [`Parameter::Query`].
14    Query {
15        /// The parameter itself.
16        parameter_data: ResolvedParameterData,
17        /// Whether reserved characters may appear unencoded.
18        allow_reserved: bool,
19        /// How the value is serialised.
20        style: QueryStyle,
21        /// Whether an empty value is allowed.
22        allow_empty_value: Option<bool>,
23    },
24    /// See [`Parameter::Header`].
25    Header {
26        /// The parameter itself.
27        parameter_data: ResolvedParameterData,
28        /// How the value is serialised.
29        style: HeaderStyle,
30    },
31    /// See [`Parameter::Path`].
32    Path {
33        /// The parameter itself.
34        parameter_data: ResolvedParameterData,
35        /// How the value is serialised.
36        style: PathStyle,
37    },
38    /// See [`Parameter::Cookie`].
39    Cookie {
40        /// The parameter itself.
41        parameter_data: ResolvedParameterData,
42        /// How the value is serialised.
43        style: CookieStyle,
44    },
45}
46
47impl ResolvedParameter {
48    /// The data shared by every kind of parameter.
49    pub fn parameter_data(&self) -> &ResolvedParameterData {
50        match self {
51            Self::Query { parameter_data, .. }
52            | Self::Header { parameter_data, .. }
53            | Self::Path { parameter_data, .. }
54            | Self::Cookie { parameter_data, .. } => parameter_data,
55        }
56    }
57}
58
59/// [`ParameterData`] with every `$ref` replaced by the item it named.
60#[derive(Debug, PartialEq)]
61pub struct ResolvedParameterData {
62    /// See [`ParameterData::name`].
63    pub name: String,
64    /// See [`ParameterData::description`].
65    pub description: Option<String>,
66    /// See [`ParameterData::required`].
67    pub required: bool,
68    /// See [`ParameterData::deprecated`].
69    pub deprecated: Option<bool>,
70    /// See [`ParameterData::format`].
71    pub format: ResolvedParameterSchemaOrContent,
72    /// See [`ParameterData::example`].
73    pub example: Option<serde_json::Value>,
74    /// See [`ParameterData::examples`].
75    pub examples: IndexMap<String, Shared<Example>>,
76    /// See [`ParameterData::explode`].
77    pub explode: Option<bool>,
78    /// See [`ParameterData::extensions`].
79    pub extensions: IndexMap<String, serde_json::Value>,
80}
81
82/// [`ParameterSchemaOrContent`] with every `$ref` replaced by the item it named.
83#[derive(Debug, PartialEq)]
84pub enum ResolvedParameterSchemaOrContent {
85    /// See [`ParameterSchemaOrContent::Schema`].
86    Schema(Shared<ResolvedSchema>),
87    /// See [`ParameterSchemaOrContent::Content`].
88    Content(IndexMap<String, ResolvedMediaType>),
89}
90
91/// [`Header`] with every `$ref` replaced by the item it named.
92#[derive(Debug, PartialEq)]
93pub struct ResolvedHeader {
94    /// See [`Header::description`].
95    pub description: Option<String>,
96    /// See [`Header::style`].
97    pub style: HeaderStyle,
98    /// See [`Header::required`].
99    pub required: bool,
100    /// See [`Header::deprecated`].
101    pub deprecated: Option<bool>,
102    /// See [`Header::format`].
103    pub format: ResolvedParameterSchemaOrContent,
104    /// See [`Header::example`].
105    pub example: Option<serde_json::Value>,
106    /// See [`Header::examples`].
107    pub examples: IndexMap<String, Shared<Example>>,
108    /// See [`Header::extensions`].
109    pub extensions: IndexMap<String, serde_json::Value>,
110}
111
112impl Resolvable for Parameter {
113    type Resolved = ResolvedParameter;
114
115    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
116        Ok(match self {
117            Self::Query {
118                parameter_data,
119                allow_reserved,
120                style,
121                allow_empty_value,
122            } => ResolvedParameter::Query {
123                parameter_data: parameter_data.resolve_inline(cx)?,
124                allow_reserved: *allow_reserved,
125                style: style.clone(),
126                allow_empty_value: *allow_empty_value,
127            },
128            Self::Header {
129                parameter_data,
130                style,
131            } => ResolvedParameter::Header {
132                parameter_data: parameter_data.resolve_inline(cx)?,
133                style: style.clone(),
134            },
135            Self::Path {
136                parameter_data,
137                style,
138            } => ResolvedParameter::Path {
139                parameter_data: parameter_data.resolve_inline(cx)?,
140                style: style.clone(),
141            },
142            Self::Cookie {
143                parameter_data,
144                style,
145            } => ResolvedParameter::Cookie {
146                parameter_data: parameter_data.resolve_inline(cx)?,
147                style: style.clone(),
148            },
149        })
150    }
151}
152
153impl Resolvable for ParameterData {
154    type Resolved = ResolvedParameterData;
155
156    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
157        Ok(ResolvedParameterData {
158            name: self.name.clone(),
159            description: self.description.clone(),
160            required: self.required,
161            deprecated: self.deprecated,
162            format: self.format.resolve_inline(cx)?,
163            example: self.example.clone(),
164            examples: cx.ref_or_map(&self.examples)?,
165            explode: self.explode,
166            extensions: self.extensions.clone(),
167        })
168    }
169}
170
171impl Resolvable for ParameterSchemaOrContent {
172    type Resolved = ResolvedParameterSchemaOrContent;
173
174    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
175        Ok(match self {
176            Self::Schema(schema) => ResolvedParameterSchemaOrContent::Schema(cx.ref_or(schema)?),
177            Self::Content(content) => {
178                ResolvedParameterSchemaOrContent::Content(super::resolve_map(content, cx)?)
179            }
180        })
181    }
182}
183
184impl Resolvable for Header {
185    type Resolved = ResolvedHeader;
186
187    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
188        Ok(ResolvedHeader {
189            description: self.description.clone(),
190            style: self.style.clone(),
191            required: self.required,
192            deprecated: self.deprecated,
193            format: self.format.resolve_inline(cx)?,
194            example: self.example.clone(),
195            examples: cx.ref_or_map(&self.examples)?,
196            extensions: self.extensions.clone(),
197        })
198    }
199}