1use std::cmp::Ordering;
44use std::collections::BTreeSet;
45use std::ops::{Deref, DerefMut};
46
47use serde::{Deserialize, Serialize};
48
49use crate::PropMap;
50
51#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Debug)]
52
53pub struct Servers(pub BTreeSet<Server>);
55impl Deref for Servers {
56 type Target = BTreeSet<Server>;
57
58 fn deref(&self) -> &Self::Target {
59 &self.0
60 }
61}
62impl DerefMut for Servers {
63 fn deref_mut(&mut self) -> &mut Self::Target {
64 &mut self.0
65 }
66}
67impl IntoIterator for Servers {
68 type Item = Server;
69 type IntoIter = <BTreeSet<Server> as IntoIterator>::IntoIter;
70
71 fn into_iter(self) -> Self::IntoIter {
72 self.0.into_iter()
73 }
74}
75impl Servers {
76 #[must_use]
78 pub fn new() -> Self {
79 Default::default()
80 }
81 #[must_use]
83 pub fn is_empty(&self) -> bool {
84 self.0.is_empty()
85 }
86 #[must_use]
88 pub fn server<S: Into<Server>>(mut self, server: S) -> Self {
89 self.insert(server);
90 self
91 }
92 pub fn insert<S: Into<Server>>(&mut self, server: S) {
94 let server = server.into();
95 let exist_server = self.0.iter().find(|s| s.url == server.url).cloned();
96 if let Some(mut exist_server) = exist_server {
97 let Server {
98 description,
99 name,
100 mut variables,
101 extensions,
102 ..
103 } = server;
104 exist_server.variables.append(&mut variables);
105 if description.is_some() {
106 exist_server.description = description;
107 }
108 if name.is_some() {
109 exist_server.name = name;
110 }
111 exist_server.extensions.extend(extensions);
112 self.0.remove(&exist_server);
113 self.0.insert(exist_server);
114 } else {
115 self.0.insert(server);
116 }
117 }
118
119 pub fn append(&mut self, other: &mut Self) {
124 let servers = std::mem::take(&mut other.0);
125 for server in servers {
126 self.insert(server);
127 }
128 }
129 pub fn extend<I>(&mut self, iter: I)
131 where
132 I: IntoIterator<Item = Server>,
133 {
134 for server in iter.into_iter() {
135 self.insert(server);
136 }
137 }
138}
139
140#[non_exhaustive]
148#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
149#[serde(rename_all = "camelCase")]
150pub struct Server {
151 pub url: String,
156
157 #[serde(skip_serializing_if = "Option::is_none")]
160 pub description: Option<String>,
161
162 #[serde(skip_serializing_if = "Option::is_none")]
167 pub name: Option<String>,
168
169 #[serde(default, skip_serializing_if = "ServerVariables::is_empty")]
171 pub variables: ServerVariables,
172
173 #[serde(skip_serializing_if = "PropMap::is_empty", flatten)]
175 pub extensions: PropMap<String, serde_json::Value>,
176}
177
178impl Ord for Server {
179 fn cmp(&self, other: &Self) -> Ordering {
180 self.url.cmp(&other.url)
181 }
182}
183impl PartialOrd for Server {
184 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
185 Some(self.cmp(other))
186 }
187}
188
189impl Server {
190 #[must_use]
214 pub fn new<S: Into<String>>(url: S) -> Self {
215 Self {
216 url: url.into(),
217 ..Default::default()
218 }
219 }
220 #[must_use]
222 pub fn url<U: Into<String>>(mut self, url: U) -> Self {
223 self.url = url.into();
224 self
225 }
226
227 #[must_use]
229 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
230 self.description = Some(description.into());
231 self
232 }
233
234 #[must_use]
236 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
237 self.name = Some(name.into());
238 self
239 }
240
241 #[must_use]
249 pub fn add_variable<N: Into<String>, V: Into<ServerVariable>>(
250 mut self,
251 name: N,
252 variable: V,
253 ) -> Self {
254 self.variables.insert(name.into(), variable.into());
255 self
256 }
257
258 #[must_use]
260 pub fn extensions(mut self, extensions: PropMap<String, serde_json::Value>) -> Self {
261 self.extensions = extensions;
262 self
263 }
264}
265
266#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
268pub struct ServerVariables(pub PropMap<String, ServerVariable>);
269impl Deref for ServerVariables {
270 type Target = PropMap<String, ServerVariable>;
271
272 fn deref(&self) -> &Self::Target {
273 &self.0
274 }
275}
276impl DerefMut for ServerVariables {
277 fn deref_mut(&mut self) -> &mut Self::Target {
278 &mut self.0
279 }
280}
281impl ServerVariables {
282 #[must_use]
285 pub fn new() -> Self {
286 Default::default()
287 }
288 #[must_use]
290 pub fn is_empty(&self) -> bool {
291 self.0.is_empty()
292 }
293 #[must_use]
295 pub fn server_variable<K: Into<String>, V: Into<ServerVariable>>(
296 mut self,
297 key: K,
298 variable: V,
299 ) -> Self {
300 self.insert(key, variable);
301 self
302 }
303 pub fn insert<K: Into<String>, V: Into<ServerVariable>>(&mut self, key: K, variable: V) {
305 let key = key.into();
306 let mut variable = variable.into();
307 self.0
308 .entry(key)
309 .and_modify(|item| {
310 if variable.description.is_some() {
311 item.description = variable.description.take();
312 }
313 item.default_value.clone_from(&variable.default_value);
314 item.enum_values.append(&mut variable.enum_values);
315 })
316 .or_insert(variable);
317 }
318 pub fn append(&mut self, other: &mut Self) {
323 let variables = std::mem::take(&mut other.0);
324 for (key, variable) in variables {
325 self.insert(key, variable);
326 }
327 }
328 pub fn extend<I>(&mut self, iter: I)
330 where
331 I: IntoIterator<Item = (String, ServerVariable)>,
332 {
333 for (key, variable) in iter.into_iter() {
334 self.insert(key, variable);
335 }
336 }
337}
338
339#[non_exhaustive]
344#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
345pub struct ServerVariable {
346 #[serde(rename = "default")]
348 default_value: String,
349
350 #[serde(skip_serializing_if = "Option::is_none")]
352 description: Option<String>,
353
354 #[serde(default, rename = "enum", skip_serializing_if = "BTreeSet::is_empty")]
357 enum_values: BTreeSet<String>,
358
359 #[serde(skip_serializing_if = "PropMap::is_empty", flatten)]
361 pub extensions: PropMap<String, serde_json::Value>,
362}
363
364impl ServerVariable {
365 #[must_use]
368 pub fn new() -> Self {
369 Default::default()
370 }
371 #[must_use]
373 pub fn default_value<S: Into<String>>(mut self, default_value: S) -> Self {
374 self.default_value = default_value.into();
375 self
376 }
377
378 #[must_use]
380 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
381 self.description = Some(description.into());
382 self
383 }
384
385 #[must_use]
387 pub fn enum_values<I: IntoIterator<Item = V>, V: Into<String>>(
388 mut self,
389 enum_values: I,
390 ) -> Self {
391 self.enum_values = enum_values.into_iter().map(|value| value.into()).collect();
392 self
393 }
394
395 #[must_use]
397 pub fn extensions(mut self, extensions: PropMap<String, serde_json::Value>) -> Self {
398 self.extensions = extensions;
399 self
400 }
401}
402
403#[cfg(test)]
404mod tests {
405 use assert_json_diff::assert_json_eq;
406 use serde_json::json;
407
408 use super::*;
409
410 macro_rules! test_fn {
411 ($name:ident : $schema:expr; $expected:literal) => {
412 #[test]
413 fn $name() {
414 let value = serde_json::to_value($schema).unwrap();
415 let expected_value: serde_json::Value = serde_json::from_str($expected).unwrap();
416
417 assert_eq!(
418 value,
419 expected_value,
420 "testing serializing \"{}\": \nactual:\n{}\nexpected:\n{}",
421 stringify!($name),
422 value,
423 expected_value
424 );
425
426 println!("{}", &serde_json::to_string_pretty(&$schema).unwrap());
427 }
428 };
429 }
430
431 test_fn! {
432 create_server_with_builder_and_variable_substitution:
433 Server::new("/api/{version}/{username}")
434 .add_variable(
435 "version",
436 ServerVariable::new()
437 .enum_values(["v1", "v2"])
438 .description("api version")
439 .default_value("v1")
440 )
441 .add_variable(
442 "username",
443 ServerVariable::new().default_value("the_user")
444 );
445 r###"{
446 "url": "/api/{version}/{username}",
447 "variables": {
448 "version": {
449 "enum": ["v1", "v2"],
450 "default": "v1",
451 "description": "api version"
452 },
453 "username": {
454 "default": "the_user"
455 }
456 }
457}"###
458 }
459
460 #[test]
461 fn test_servers_is_empty() {
462 let servers = Servers::new();
463 assert!(servers.is_empty());
464 }
465
466 #[test]
467 fn test_servers_server() {
468 let servers = Servers::new();
469 let server = Server::new("/api/v1").description("api v1");
470 let servers = servers.server(server);
471 assert_eq!(servers.len(), 1);
472 }
473
474 #[test]
475 fn test_servers_insert() {
476 let mut servers = Servers::new();
477 let server = Server::new("/api/v1").description("api v1");
478 servers.insert(server);
479 assert_eq!(servers.len(), 1);
480 }
481
482 #[test]
483 fn test_servers_insert_existed_server() {
484 let mut servers = Servers::new();
485 let server1 = Server::new("/api/v1".to_owned())
486 .description("api v1")
487 .add_variable("key1", ServerVariable::new());
488 servers.insert(server1);
489
490 let server2 = Server::new("/api/v1".to_owned())
491 .description("api v1 new description")
492 .add_variable("key2", ServerVariable::new());
493 servers.insert(server2);
494
495 assert_eq!(servers.len(), 1);
496 assert_json_eq!(
497 servers,
498 json!([
499 {
500 "description": "api v1 new description",
501 "url": "/api/v1",
502 "variables": {
503 "key1": {
504 "default": ""
505 },
506 "key2": {
507 "default": ""
508 }
509 }
510 }
511 ])
512 )
513 }
514
515 #[test]
516 fn test_servers_append() {
517 let mut servers = Servers::new();
518
519 let server = Server::new("/api/v1").description("api v1");
520 let mut other_servers: Servers = Servers::new();
521
522 other_servers.insert(server);
523 assert!(!other_servers.is_empty());
524
525 servers.append(&mut other_servers);
526 assert!(!servers.is_empty());
527 }
528
529 #[test]
530 fn test_servers_extend() {
531 let mut servers = Servers::new();
532
533 let server = Server::new("/api/v1").description("api v1");
534 let mut other_servers: Servers = Servers::new();
535
536 other_servers.insert(server);
537 assert!(!other_servers.is_empty());
538
539 servers.extend(other_servers);
540 assert!(!servers.is_empty());
541 }
542
543 #[test]
544 fn test_servers_deref() {
545 let mut servers = Servers::new();
546 let server = Server::new("/api/v1").description("api v1");
547 servers.insert(server);
548 assert_eq!(servers.len(), 1);
549 assert_eq!(servers.deref().len(), 1);
550
551 servers.deref_mut().clear();
552 assert!(servers.is_empty());
553 }
554
555 #[test]
556 fn test_server_set_url() {
557 let server = Server::new("/api/v1");
558 assert_eq!(server.url, "/api/v1");
559
560 let server = server.url("/new/api/v1");
561 assert_eq!(server.url, "/new/api/v1");
562 }
563
564 #[test]
565 fn test_server_cmp() {
566 let server_a = Server::new("/api/v1");
567 let server_b = Server::new("/api/v2");
568 assert!(server_a < server_b);
569 }
570
571 #[test]
572 fn test_server_variables_is_empty() {
573 let server_variables = ServerVariables::new();
574 assert!(server_variables.is_empty());
575 }
576
577 #[test]
578 fn test_server_variables_server_variable() {
579 let server_variables = ServerVariables::new();
580 let variable = ServerVariable::new();
581 let server_variables = server_variables.server_variable("key", variable);
582
583 assert!(!server_variables.is_empty());
584 }
585
586 #[test]
587 fn test_server_variables_insert() {
588 let mut server_variables = ServerVariables::new();
589 let variable = ServerVariable::new();
590 server_variables.insert("key", variable);
591 assert_eq!(server_variables.len(), 1);
592
593 let new_variable = ServerVariable::new().description("description");
594 server_variables.insert("key", new_variable);
595 assert_eq!(server_variables.len(), 1);
596 }
597
598 #[test]
599 fn test_server_variables_append() {
600 let mut server_variables = ServerVariables::new();
601
602 let mut other_server_variables = ServerVariables::new();
603 let variable = ServerVariable::new();
604 other_server_variables.insert("key", variable);
605
606 server_variables.append(&mut other_server_variables);
607 assert_eq!(server_variables.len(), 1);
608 }
609
610 #[test]
611 fn test_server_variables_extend() {
612 let mut server_variables = ServerVariables::new();
613
614 let mut other_server_variables = ServerVariables::new();
615 let variable = ServerVariable::new();
616 other_server_variables.insert("key", variable);
617
618 server_variables.extend(other_server_variables.0);
619 assert_eq!(server_variables.len(), 1);
620 }
621
622 #[test]
623 fn test_server_variables_deref() {
624 let mut server_variables = ServerVariables::new();
625
626 let variable = ServerVariable::new().default_value("default_value");
627 server_variables.insert("key", variable);
628
629 assert!(!server_variables.is_empty());
630 assert_eq!(server_variables.deref().len(), 1);
631
632 server_variables.deref_mut().clear();
633 assert!(server_variables.is_empty());
634 }
635}