1use std::cmp::Ordering;
42use std::collections::BTreeSet;
43use std::ops::{Deref, DerefMut};
44
45use serde::{Deserialize, Serialize};
46
47use crate::PropMap;
48
49#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Debug)]
50
51pub struct Servers(pub BTreeSet<Server>);
53impl Deref for Servers {
54 type Target = BTreeSet<Server>;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60impl DerefMut for Servers {
61 fn deref_mut(&mut self) -> &mut Self::Target {
62 &mut self.0
63 }
64}
65impl IntoIterator for Servers {
66 type Item = Server;
67 type IntoIter = <BTreeSet<Server> as IntoIterator>::IntoIter;
68
69 fn into_iter(self) -> Self::IntoIter {
70 self.0.into_iter()
71 }
72}
73impl Servers {
74 pub fn new() -> Self {
76 Default::default()
77 }
78 pub fn is_empty(&self) -> bool {
80 self.0.is_empty()
81 }
82 pub fn server<S: Into<Server>>(mut self, server: S) -> Self {
84 self.insert(server);
85 self
86 }
87 pub fn insert<S: Into<Server>>(&mut self, server: S) {
89 let server = server.into();
90 let exist_server = self.0.iter().find(|s| s.url == server.url).cloned();
91 if let Some(mut exist_server) = exist_server {
92 let Server {
93 description,
94 mut variables,
95 ..
96 } = server;
97 exist_server.variables.append(&mut variables);
98 if description.is_some() {
99 exist_server.description = description;
100 }
101 self.0.remove(&exist_server);
102 self.0.insert(exist_server);
103 } else {
104 self.0.insert(server);
105 }
106 }
107
108 pub fn append(&mut self, other: &mut Servers) {
113 let servers = std::mem::take(&mut other.0);
114 for server in servers {
115 self.insert(server);
116 }
117 }
118 pub fn extend<I>(&mut self, iter: I)
120 where
121 I: IntoIterator<Item = Server>,
122 {
123 for server in iter.into_iter() {
124 self.insert(server);
125 }
126 }
127}
128
129#[non_exhaustive]
137#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
138#[serde(rename_all = "camelCase")]
139pub struct Server {
140 pub url: String,
145
146 #[serde(skip_serializing_if = "Option::is_none")]
148 pub description: Option<String>,
149
150 #[serde(skip_serializing_if = "ServerVariables::is_empty")]
152 pub variables: ServerVariables,
153}
154
155impl Ord for Server {
156 fn cmp(&self, other: &Self) -> Ordering {
157 self.url.cmp(&other.url)
158 }
159}
160impl PartialOrd for Server {
161 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
162 Some(self.cmp(other))
163 }
164}
165
166impl Server {
167 pub fn new<S: Into<String>>(url: S) -> Self {
189 Self {
190 url: url.into(),
191 ..Default::default()
192 }
193 }
194 pub fn url<U: Into<String>>(mut self, url: U) -> Self {
196 self.url = url.into();
197 self
198 }
199
200 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
202 self.description = Some(description.into());
203 self
204 }
205
206 pub fn add_variable<N: Into<String>, V: Into<ServerVariable>>(
213 mut self,
214 name: N,
215 variable: V,
216 ) -> Self {
217 self.variables.insert(name.into(), variable.into());
218 self
219 }
220}
221
222#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
224pub struct ServerVariables(pub PropMap<String, ServerVariable>);
225impl Deref for ServerVariables {
226 type Target = PropMap<String, ServerVariable>;
227
228 fn deref(&self) -> &Self::Target {
229 &self.0
230 }
231}
232impl DerefMut for ServerVariables {
233 fn deref_mut(&mut self) -> &mut Self::Target {
234 &mut self.0
235 }
236}
237impl ServerVariables {
238 pub fn new() -> Self {
240 Default::default()
241 }
242 pub fn is_empty(&self) -> bool {
244 self.0.is_empty()
245 }
246 pub fn server_varible<K: Into<String>, V: Into<ServerVariable>>(
248 mut self,
249 key: K,
250 variable: V,
251 ) -> Self {
252 self.insert(key, variable);
253 self
254 }
255 pub fn insert<K: Into<String>, V: Into<ServerVariable>>(&mut self, key: K, variable: V) {
257 let key = key.into();
258 let mut variable = variable.into();
259 self.0
260 .entry(key)
261 .and_modify(|item| {
262 if variable.description.is_some() {
263 item.description = variable.description.take();
264 }
265 item.default_value.clone_from(&variable.default_value);
266 item.enum_values.append(&mut variable.enum_values);
267 })
268 .or_insert(variable);
269 }
270 pub fn append(&mut self, other: &mut ServerVariables) {
275 let variables = std::mem::take(&mut other.0);
276 for (key, variable) in variables {
277 self.insert(key, variable);
278 }
279 }
280 pub fn extend<I>(&mut self, iter: I)
282 where
283 I: IntoIterator<Item = (String, ServerVariable)>,
284 {
285 for (key, variable) in iter.into_iter() {
286 self.insert(key, variable);
287 }
288 }
289}
290
291#[non_exhaustive]
295#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
296pub struct ServerVariable {
297 #[serde(rename = "default")]
299 default_value: String,
300
301 #[serde(skip_serializing_if = "Option::is_none")]
303 description: Option<String>,
304
305 #[serde(rename = "enum", skip_serializing_if = "BTreeSet::is_empty")]
308 enum_values: BTreeSet<String>,
309}
310
311impl ServerVariable {
312 pub fn new() -> Self {
314 Default::default()
315 }
316 pub fn default_value<S: Into<String>>(mut self, default_value: S) -> Self {
318 self.default_value = default_value.into();
319 self
320 }
321
322 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
324 self.description = Some(description.into());
325 self
326 }
327
328 pub fn enum_values<I: IntoIterator<Item = V>, V: Into<String>>(
330 mut self,
331 enum_values: I,
332 ) -> Self {
333 self.enum_values = enum_values.into_iter().map(|value| value.into()).collect();
334 self
335 }
336}
337
338#[cfg(test)]
339mod tests {
340 use assert_json_diff::assert_json_eq;
341 use serde_json::json;
342
343 use super::*;
344
345 macro_rules! test_fn {
346 ($name:ident: $schema:expr; $expected:literal) => {
347 #[test]
348 fn $name() {
349 let value = serde_json::to_value($schema).unwrap();
350 let expected_value: serde_json::Value = serde_json::from_str($expected).unwrap();
351
352 assert_eq!(
353 value,
354 expected_value,
355 "testing serializing \"{}\": \nactual:\n{}\nexpected:\n{}",
356 stringify!($name),
357 value,
358 expected_value
359 );
360
361 println!("{}", &serde_json::to_string_pretty(&$schema).unwrap());
362 }
363 };
364 }
365
366 test_fn! {
367 create_server_with_builder_and_variable_substitution:
368 Server::new("/api/{version}/{username}")
369 .add_variable(
370 "version",
371 ServerVariable::new()
372 .enum_values(["v1", "v2"])
373 .description("api version")
374 .default_value("v1")
375 )
376 .add_variable(
377 "username",
378 ServerVariable::new().default_value("the_user")
379 );
380 r###"{
381 "url": "/api/{version}/{username}",
382 "variables": {
383 "version": {
384 "enum": ["v1", "v2"],
385 "default": "v1",
386 "description": "api version"
387 },
388 "username": {
389 "default": "the_user"
390 }
391 }
392}"###
393 }
394
395 #[test]
396 fn test_servers_is_empty() {
397 let servers = Servers::new();
398 assert!(servers.is_empty());
399 }
400
401 #[test]
402 fn test_servers_server() {
403 let servers = Servers::new();
404 let server = Server::new("/api/v1").description("api v1");
405 let servers = servers.server(server);
406 assert!(servers.len() == 1);
407 }
408
409 #[test]
410 fn test_servers_insert() {
411 let mut servers = Servers::new();
412 let server = Server::new("/api/v1").description("api v1");
413 servers.insert(server);
414 assert!(servers.len() == 1);
415 }
416
417 #[test]
418 fn test_servers_insert_existed_server() {
419 let mut servers = Servers::new();
420 let server1 = Server::new("/api/v1".to_string())
421 .description("api v1")
422 .add_variable("key1", ServerVariable::new());
423 servers.insert(server1);
424
425 let server2 = Server::new("/api/v1".to_string())
426 .description("api v1 new description")
427 .add_variable("key2", ServerVariable::new());
428 servers.insert(server2);
429
430 assert!(servers.len() == 1);
431 assert_json_eq!(
432 servers,
433 json!([
434 {
435 "description": "api v1 new description",
436 "url": "/api/v1",
437 "variables": {
438 "key1": {
439 "default": ""
440 },
441 "key2": {
442 "default": ""
443 }
444 }
445 }
446 ])
447 )
448 }
449
450 #[test]
451 fn test_servers_append() {
452 let mut servers = Servers::new();
453
454 let server = Server::new("/api/v1").description("api v1");
455 let mut other_servers: Servers = Servers::new();
456
457 other_servers.insert(server);
458 assert!(!other_servers.is_empty());
459
460 servers.append(&mut other_servers);
461 assert!(!servers.is_empty());
462 }
463
464 #[test]
465 fn test_servers_extend() {
466 let mut servers = Servers::new();
467
468 let server = Server::new("/api/v1").description("api v1");
469 let mut other_servers: Servers = Servers::new();
470
471 other_servers.insert(server);
472 assert!(!other_servers.is_empty());
473
474 servers.extend(other_servers);
475 assert!(!servers.is_empty());
476 }
477
478 #[test]
479 fn test_servers_deref() {
480 let mut servers = Servers::new();
481 let server = Server::new("/api/v1").description("api v1");
482 servers.insert(server);
483 assert!(servers.len() == 1);
484 assert!(servers.deref().len() == 1);
485
486 servers.deref_mut().clear();
487 assert!(servers.is_empty());
488 }
489
490 #[test]
491 fn test_server_set_url() {
492 let server = Server::new("/api/v1");
493 assert_eq!(server.url, "/api/v1");
494
495 let server = server.url("/new/api/v1");
496 assert_eq!(server.url, "/new/api/v1");
497 }
498
499 #[test]
500 fn test_server_cmp() {
501 let server_a = Server::new("/api/v1");
502 let server_b = Server::new("/api/v2");
503 assert!(server_a < server_b);
504 }
505
506 #[test]
507 fn test_server_variables_is_empty() {
508 let server_variables = ServerVariables::new();
509 assert!(server_variables.is_empty());
510 }
511
512 #[test]
513 fn test_server_variables_server_varible() {
514 let server_variables = ServerVariables::new();
515 let variable = ServerVariable::new();
516 let server_variables = server_variables.server_varible("key", variable);
517
518 assert!(!server_variables.is_empty());
519 }
520
521 #[test]
522 fn test_server_variables_insert() {
523 let mut server_variables = ServerVariables::new();
524 let variable = ServerVariable::new();
525 server_variables.insert("key", variable);
526 assert!(server_variables.len() == 1);
527
528 let new_variable = ServerVariable::new().description("description");
529 server_variables.insert("key", new_variable);
530 assert!(server_variables.len() == 1);
531 }
532
533 #[test]
534 fn test_server_variables_append() {
535 let mut server_variables = ServerVariables::new();
536
537 let mut other_server_variables = ServerVariables::new();
538 let variable = ServerVariable::new();
539 other_server_variables.insert("key", variable);
540
541 server_variables.append(&mut other_server_variables);
542 assert!(server_variables.len() == 1);
543 }
544
545 #[test]
546 fn test_server_variables_extend() {
547 let mut server_variables = ServerVariables::new();
548
549 let mut other_server_variables = ServerVariables::new();
550 let variable = ServerVariable::new();
551 other_server_variables.insert("key", variable);
552
553 server_variables.extend(other_server_variables.0);
554 assert!(server_variables.len() == 1);
555 }
556
557 #[test]
558 fn test_server_variables_deref() {
559 let mut server_variables = ServerVariables::new();
560
561 let variable = ServerVariable::new().default_value("default_value");
562 server_variables.insert("key", variable);
563
564 assert!(!server_variables.is_empty());
565 assert!(server_variables.deref().len() == 1);
566
567 server_variables.deref_mut().clear();
568 assert!(server_variables.is_empty());
569 }
570}