openapiv3/
parameter.rs

1use crate::*;
2use indexmap::IndexMap;
3use serde::{Deserialize, Serialize};
4
5/// Describes a single operation parameter.
6///
7/// A unique parameter is defined by a combination of a name and location.
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9pub struct ParameterData {
10    /// REQUIRED. The name of the parameter. Parameter names are case sensitive.
11    /// If in is "path", the name field MUST correspond to the associated path
12    /// segment from the path field in the Paths Object. See Path Templating for
13    /// further information.
14    ///
15    /// If in is "header" and the name field is "Accept", "Content-Type" or
16    /// "Authorization", the parameter definition SHALL be ignored.
17    ///
18    /// For all other cases, the name corresponds to the parameter name
19    /// used by the in property.
20    pub name: String,
21    /// A brief description of the parameter. This could
22    /// contain examples of use. CommonMark syntax MAY be
23    /// used for rich text representation.
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub description: Option<String>,
26    /// Determines whether this parameter is mandatory.
27    /// If the parameter location is "path", this property
28    /// is REQUIRED and its value MUST be true. Otherwise,
29    /// the property MAY be included and its default value
30    /// is false.
31    #[serde(default, skip_serializing_if = "is_false")]
32    pub required: bool,
33    /// Specifies that a parameter is deprecated and SHOULD
34    /// be transitioned out of usage.
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub deprecated: Option<bool>,
37    #[serde(flatten)]
38    pub format: ParameterSchemaOrContent,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub example: Option<serde_json::Value>,
41    #[serde(default, skip_serializing_if = "IndexMap::is_empty")]
42    pub examples: IndexMap<String, RefOr<Example>>,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub explode: Option<bool>,
45    /// Inline extensions to this object.
46    #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
47    pub extensions: IndexMap<String, serde_json::Value>,
48}
49
50
51impl ParameterData {
52    /// Returns the parameter schema if it exists.
53    pub fn schema(&self) -> Option<&RefOr<Schema>> {
54        match self.format {
55            ParameterSchemaOrContent::Schema(ref schema) => Some(schema),
56            ParameterSchemaOrContent::Content(_) => None
57        }
58    }
59}
60
61
62#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
63#[serde(rename_all = "camelCase")]
64pub enum ParameterSchemaOrContent {
65    /// The schema defining the type used for the parameter.
66    Schema(RefOr<Schema>),
67    /// A map containing the representations for the parameter. The key is the
68    /// media type and the value describes it. The map MUST only contain one
69    /// entry.
70    Content(Content),
71}
72
73pub type Content = IndexMap<String, MediaType>;
74
75#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
76pub struct Parameter {
77    #[serde(flatten)]
78    pub data: ParameterData,
79    #[serde(flatten)]
80    pub kind: ParameterKind,
81}
82
83impl std::ops::Deref for Parameter {
84    type Target = ParameterData;
85
86    fn deref(&self) -> &Self::Target {
87        &self.data
88    }
89}
90
91impl std::ops::DerefMut for Parameter {
92    fn deref_mut(&mut self) -> &mut Self::Target {
93        &mut self.data
94    }
95}
96
97#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
98#[serde(tag = "in", rename_all = "camelCase")]
99pub enum ParameterKind {
100    #[serde(rename_all = "camelCase")]
101    Query {
102        /// Determines whether the parameter value SHOULD allow reserved
103        /// characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included
104        /// without percent-encoding. This property only applies to parameters
105        /// with an in value of query. The default value is false.
106        #[serde(default, skip_serializing_if = "is_false")]
107        allow_reserved: bool,
108        /// Describes how the parameter value will be serialized depending on
109        /// the type of the parameter value. Default values (based on value of
110        /// in): for query - form; for path - simple; for header - simple; for
111        /// cookie - form.
112        #[serde(default, skip_serializing_if = "SkipSerializeIfDefault::skip")]
113        style: QueryStyle,
114        /// Sets the ability to pass empty-valued parameters. This is
115        /// valid only for query parameters and allows sending a parameter
116        /// with an empty value. Default value is false. If style is used,
117        /// and if behavior is n/a (cannot be serialized), the value of
118        /// allowEmptyValue SHALL be ignored.
119        #[serde(skip_serializing_if = "Option::is_none")]
120        allow_empty_value: Option<bool>,
121    },
122    Header {
123        /// Describes how the parameter value will be serialized depending on
124        /// the type of the parameter value. Default values (based on value of
125        /// in): for query - form; for path - simple; for header - simple; for
126        /// cookie - form.
127        #[serde(default, skip_serializing_if = "SkipSerializeIfDefault::skip")]
128        style: HeaderStyle,
129    },
130    Path {
131        /// Describes how the parameter value will be serialized depending on
132        /// the type of the parameter value. Default values (based on value of
133        /// in): for query - form; for path - simple; for header - simple; for
134        /// cookie - form.
135        #[serde(default, skip_serializing_if = "SkipSerializeIfDefault::skip")]
136        style: PathStyle,
137    },
138    Cookie {
139        /// Describes how the parameter value will be serialized depending on
140        /// the type of the parameter value. Default values (based on value of
141        /// in): for query - form; for path - simple; for header - simple; for
142        /// cookie - form.
143        #[serde(default, skip_serializing_if = "SkipSerializeIfDefault::skip")]
144        style: CookieStyle,
145    },
146}
147
148impl Parameter {
149    fn new_kind(name: String, schema: RefOr<Schema>, kind: ParameterKind) -> Self {
150        Parameter {
151            data: ParameterData {
152                name,
153                description: None,
154                required: false,
155                deprecated: None,
156                format: ParameterSchemaOrContent::Schema(schema),
157                example: None,
158                examples: Default::default(),
159                explode: None,
160                extensions: Default::default(),
161            },
162            kind,
163        }
164    }
165
166    pub fn query(name: impl Into<String>, schema: impl Into<RefOr<Schema>>) -> Self {
167        Self::new_kind(name.into(), schema.into(), ParameterKind::Query {
168            allow_reserved: false,
169            style: QueryStyle::Form,
170            allow_empty_value: None,
171        })
172    }
173
174    pub fn path(name: impl Into<String>, schema: impl Into<RefOr<Schema>>) -> Self {
175        Self::new_kind(name.into(), schema.into(), ParameterKind::Path {
176            style: PathStyle::Simple,
177        })
178    }
179}
180
181struct SkipSerializeIfDefault;
182
183impl SkipSerializeIfDefault {
184    #[cfg(feature = "skip_serializing_defaults")]
185    fn skip<D: Default + std::cmp::PartialEq>(value: &D) -> bool {
186        value == &Default::default()
187    }
188    #[cfg(not(feature = "skip_serializing_defaults"))]
189    fn skip<D: Default + std::cmp::PartialEq>(_value: &D) -> bool {
190        false
191    }
192}
193
194#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
195#[serde(rename_all = "camelCase")]
196pub enum PathStyle {
197    Matrix,
198    Label,
199    #[default]
200    Simple,
201}
202
203#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
204#[serde(rename_all = "camelCase")]
205pub enum QueryStyle {
206    #[default]
207    Form,
208    SpaceDelimited,
209    PipeDelimited,
210    DeepObject,
211}
212
213#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
214#[serde(rename_all = "camelCase")]
215pub enum CookieStyle {
216    #[default]
217    Form,
218}
219#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
220#[serde(rename_all = "camelCase")]
221pub enum HeaderStyle {
222    #[default]
223    Simple,
224}