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#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
25#[serde(default, rename_all = "camelCase")]
26pub struct Parameter {
27 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 #[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
45 pub x_fields: HashMap<String, Value>,
46
47 #[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 #[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#[derive(Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
145#[serde(rename_all = "camelCase")]
146pub enum ParameterStyle {
147 Matrix,
149 Label,
151 Form,
154 Simple,
157 SpaceDelimited,
160 PipeDelimited,
163 DeepObject,
165}
166impl Default for ParameterStyle {
167 fn default() -> Self { Self::Simple }
168}