1use crate::*;
2use indexmap::IndexMap;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
7#[serde(rename_all = "camelCase")]
8pub struct Operation {
9 #[serde(default)]
13 #[serde(skip_serializing_if = "Vec::is_empty")]
14 pub tags: Vec<String>,
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub summary: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
21 pub description: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub external_docs: Option<ExternalDocumentation>,
25 #[serde(skip_serializing_if = "Option::is_none")]
31 pub operation_id: Option<String>,
32 #[serde(default)]
40 #[serde(skip_serializing_if = "Vec::is_empty")]
41 pub parameters: Vec<RefOr<Parameter>>,
42 #[serde(skip_serializing_if = "Option::is_none")]
48 pub request_body: Option<RefOr<RequestBody>>,
49 pub responses: Responses,
52 #[serde(default, skip_serializing_if = "is_false")]
54 pub deprecated: bool,
55 #[serde(default)]
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub security: Option<Vec<SecurityRequirement>>,
63 #[serde(default)]
67 #[serde(skip_serializing_if = "Vec::is_empty")]
68 pub servers: Vec<Server>,
69 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
71 pub extensions: IndexMap<String, serde_json::Value>,
72}
73
74impl Operation {
75 pub fn add_response_success_json(&mut self, schema: Option<RefOr<Schema>>) {
76 self.responses.responses.insert(StatusCode::Code(200), RefOr::Item({
77 let mut content = indexmap::IndexMap::new();
78 content.insert("application/json".to_string(), MediaType {
79 schema,
80 ..MediaType::default()
81 });
82 Response {
83 content,
84 ..Response::default()
85 }
86 }));
87 }
88
89 pub fn add_request_body_json(&mut self, schema: Option<RefOr<Schema>>) {
90 let mut content = indexmap::IndexMap::new();
91 content.insert("application/json".to_string(), MediaType {
92 schema,
93 ..MediaType::default()
94 });
95 self.request_body = Some(RefOr::Item(RequestBody {
96 content,
97 required: true,
98 ..RequestBody::default()
99 }));
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use crate::{Operation, RefOr, Responses, Schema, StatusCode};
106 use indexmap::IndexMap;
107 use serde_yaml::from_str;
108
109 #[test]
110 fn deserialize_responses() {
111 assert_eq!(
112 Operation {
113 responses: Responses {
114 default: None,
115 responses: {
116 let mut map = IndexMap::new();
117 map.insert(StatusCode::Code(200), RefOr::ref_("test"));
118 map
119 },
120 ..Default::default()
121 },
122 ..Default::default()
123 },
124 from_str("{ responses: { 200: { $ref: 'test' } } }").unwrap(),
125 );
126
127 assert_eq!(
128 Operation {
129 responses: Responses {
130 default: None,
131 responses: {
132 let mut map = IndexMap::new();
133 map.insert(StatusCode::Code(666), RefOr::ref_("demo"));
134 map
135 },
136 ..Default::default()
137 },
138 ..Default::default()
139 },
140 from_str("{ responses: { \"666\": { $ref: 'demo' } } }").unwrap(),
141 );
142
143 assert_eq!(
144 Operation {
145 responses: Responses {
146 default: Some(RefOr::ref_("def")),
147 responses: {
148 let mut map = IndexMap::new();
149 map.insert(StatusCode::Code(666), RefOr::ref_("demo"));
150 map.insert(StatusCode::Code(418), RefOr::ref_("demo"));
151 map
152 },
153 ..Default::default()
154 },
155 ..Default::default()
156 },
157 from_str("{ responses: { default: { $ref: 'def' }, \"666\": { $ref: 'demo' }, 418: { $ref: 'demo' } } }").unwrap(),
158 );
159 }
160
161 #[test]
162 fn test_basic() {
163 let mut op = Operation::default();
164 op.add_request_body_json(Some(RefOr::Item(Schema::new_string())));
165 }
166}