sw4rm_rs/shared/
parameter.rs

1use std::collections::HashMap;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::{
6    Spec,
7    reference::*,
8    shared::{
9        ParameterLocation,
10        Schema,
11    },
12    openapi_v2::Items,
13    openapi_v3_0::{
14        Example,
15        MediaType,
16    },
17};
18
19/// Parameter Object
20///
21/// Describes a single operation parameter.
22/// Also implicitly used for `Header`, with `name` as the key of the containing hashmap and
23/// `location` being implied as `Header`
24#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
25#[serde(default, rename_all = "camelCase")]
26pub struct Parameter {
27    // MARK: Common Fields
28
29    pub name: Option<String>,
30    #[serde(rename = "in")]
31    pub location: Option<ParameterLocation>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub description: Option<String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub required: Option<bool>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub schema: Option<RefOr<Schema>>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub allow_empty_value: Option<bool>,
40
41    /// Allows extensions to the Swagger Schema. The field name MUST begin with x-, for example,
42    /// x-internal-id. The value can be null, a primitive, an array or an object. See Vendor
43    /// Extensions for further details.
44    #[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
45    pub x_fields: HashMap<String, Value>,
46
47    // MARK: OpenAPI v2 Fields
48
49    #[serde(rename = "schema", skip_serializing_if = "Option::is_none")]
50    pub schema_type: Option<ParameterSchemaType>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub format: Option<String>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub items: Option<Items>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub collection_format: Option<String>,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub default: Option<Value>,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub maximum: Option<f64>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub exclusive_maximum: Option<bool>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub minimum: Option<f64>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub exclusive_minimum: Option<bool>,
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub max_length: Option<i64>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub min_length: Option<i64>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub pattern: Option<String>,
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub max_items: Option<i64>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub min_items: Option<i64>,
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub unique_items: Option<bool>,
79    #[serde(rename = "enum", skip_serializing_if = "Vec::is_empty")]
80    pub enum_values: Vec<Value>,
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub multiple_of: Option<i64>,
83
84    // MARK: OpenAPI v3 Fields
85
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub deprecated: Option<bool>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub style: Option<ParameterStyle>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub explode: Option<bool>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub allow_reserved: Option<bool>,
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub example: Option<Value>,
96    #[serde(skip_serializing_if = "HashMap::is_empty")]
97    pub examples: HashMap<String, RefOr<Example>>,
98    #[serde(skip_serializing_if = "HashMap::is_empty")]
99    pub content: HashMap<String, MediaType>,
100}
101impl Resolvable for Parameter {
102    fn resolve(spec: &Spec, path: &String) -> Result<Self, ResolveError> {
103        let path = path.clone();
104        let reference: Reference = path.clone().try_into().unwrap();
105
106        match reference.kind {
107            ReferenceType::Parameter => {
108               if spec.semver_check("=2") {
109                   spec.parameters.get(&reference.name)
110                       .ok_or_else(|| ResolveError::UnknownPathError(path))
111                       .and_then(|t| t.resolve(spec))
112               } else {
113                   spec.components
114                      .as_ref()
115                      .ok_or_else(|| ResolveError::UnknownPathError(path.clone()))
116                      .and_then(|c| c.parameters.get(&reference.name).ok_or_else(|| ResolveError::UnknownPathError(path)))
117                      .and_then(|p| p.resolve(spec))
118               }
119            },
120            _ => Err(ResolveError::UnknownPathError(path)),
121        }
122    }
123}
124
125#[derive(Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
126#[serde(rename_all = "lowercase")]
127pub enum ParameterSchemaType {
128    String,
129    Number,
130    Integer,
131    Boolean,
132    Array,
133    File,
134    Object,
135}
136impl Default for ParameterSchemaType {
137    fn default() -> Self { Self::String }
138}
139
140/// ParameterStyle
141///
142/// In order to support common ways of serializing simple parameters, a set of style values
143/// are defined.
144#[derive(Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
145#[serde(rename_all = "camelCase")]
146pub enum ParameterStyle {
147    /// Path-style parameters defined by RFC6570
148    Matrix,
149    /// Label style parameters defined by RFC6570
150    Label,
151    /// Form style parameters defined by RFC6570. This option replaces collectionFormat with a
152    /// csv (when explode is false) or multi (when explode is true) value from OpenAPI 2.0.
153    Form,
154    /// Simple style parameters defined by RFC6570. This option replaces collectionFormat with a
155    /// csv value from OpenAPI 2.0.
156    Simple,
157    /// Space separated array values. This option replaces collectionFormat equal to ssv from
158    /// OpenAPI 2.0.
159    SpaceDelimited,
160    /// Pipe separated array values. This option replaces collectionFormat equal to pipes from
161    /// OpenAPI 2.0.
162    PipeDelimited,
163    /// Provides a simple way of rendering nested objects using form parameters.
164    DeepObject,
165}
166impl Default for ParameterStyle {
167    fn default() -> Self { Self::Simple }
168}