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 mut variables,
100 ..
101 } = server;
102 exist_server.variables.append(&mut variables);
103 if description.is_some() {
104 exist_server.description = description;
105 }
106 self.0.remove(&exist_server);
107 self.0.insert(exist_server);
108 } else {
109 self.0.insert(server);
110 }
111 }
112
113 pub fn append(&mut self, other: &mut Self) {
118 let servers = std::mem::take(&mut other.0);
119 for server in servers {
120 self.insert(server);
121 }
122 }
123 pub fn extend<I>(&mut self, iter: I)
125 where
126 I: IntoIterator<Item = Server>,
127 {
128 for server in iter.into_iter() {
129 self.insert(server);
130 }
131 }
132}
133
134#[non_exhaustive]
142#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
143#[serde(rename_all = "camelCase")]
144pub struct Server {
145 pub url: String,
150
151 #[serde(skip_serializing_if = "Option::is_none")]
154 pub description: Option<String>,
155
156 #[serde(skip_serializing_if = "ServerVariables::is_empty")]
158 pub variables: ServerVariables,
159}
160
161impl Ord for Server {
162 fn cmp(&self, other: &Self) -> Ordering {
163 self.url.cmp(&other.url)
164 }
165}
166impl PartialOrd for Server {
167 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
168 Some(self.cmp(other))
169 }
170}
171
172impl Server {
173 #[must_use]
197 pub fn new<S: Into<String>>(url: S) -> Self {
198 Self {
199 url: url.into(),
200 ..Default::default()
201 }
202 }
203 #[must_use]
205 pub fn url<U: Into<String>>(mut self, url: U) -> Self {
206 self.url = url.into();
207 self
208 }
209
210 #[must_use]
212 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
213 self.description = Some(description.into());
214 self
215 }
216
217 #[must_use]
225 pub fn add_variable<N: Into<String>, V: Into<ServerVariable>>(
226 mut self,
227 name: N,
228 variable: V,
229 ) -> Self {
230 self.variables.insert(name.into(), variable.into());
231 self
232 }
233}
234
235#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
237pub struct ServerVariables(pub PropMap<String, ServerVariable>);
238impl Deref for ServerVariables {
239 type Target = PropMap<String, ServerVariable>;
240
241 fn deref(&self) -> &Self::Target {
242 &self.0
243 }
244}
245impl DerefMut for ServerVariables {
246 fn deref_mut(&mut self) -> &mut Self::Target {
247 &mut self.0
248 }
249}
250impl ServerVariables {
251 #[must_use]
254 pub fn new() -> Self {
255 Default::default()
256 }
257 #[must_use]
259 pub fn is_empty(&self) -> bool {
260 self.0.is_empty()
261 }
262 #[must_use]
264 pub fn server_variable<K: Into<String>, V: Into<ServerVariable>>(
265 mut self,
266 key: K,
267 variable: V,
268 ) -> Self {
269 self.insert(key, variable);
270 self
271 }
272 pub fn insert<K: Into<String>, V: Into<ServerVariable>>(&mut self, key: K, variable: V) {
274 let key = key.into();
275 let mut variable = variable.into();
276 self.0
277 .entry(key)
278 .and_modify(|item| {
279 if variable.description.is_some() {
280 item.description = variable.description.take();
281 }
282 item.default_value.clone_from(&variable.default_value);
283 item.enum_values.append(&mut variable.enum_values);
284 })
285 .or_insert(variable);
286 }
287 pub fn append(&mut self, other: &mut Self) {
292 let variables = std::mem::take(&mut other.0);
293 for (key, variable) in variables {
294 self.insert(key, variable);
295 }
296 }
297 pub fn extend<I>(&mut self, iter: I)
299 where
300 I: IntoIterator<Item = (String, ServerVariable)>,
301 {
302 for (key, variable) in iter.into_iter() {
303 self.insert(key, variable);
304 }
305 }
306}
307
308#[non_exhaustive]
313#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
314pub struct ServerVariable {
315 #[serde(rename = "default")]
317 default_value: String,
318
319 #[serde(skip_serializing_if = "Option::is_none")]
321 description: Option<String>,
322
323 #[serde(rename = "enum", skip_serializing_if = "BTreeSet::is_empty")]
326 enum_values: BTreeSet<String>,
327}
328
329impl ServerVariable {
330 #[must_use]
333 pub fn new() -> Self {
334 Default::default()
335 }
336 #[must_use]
338 pub fn default_value<S: Into<String>>(mut self, default_value: S) -> Self {
339 self.default_value = default_value.into();
340 self
341 }
342
343 #[must_use]
345 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
346 self.description = Some(description.into());
347 self
348 }
349
350 #[must_use]
352 pub fn enum_values<I: IntoIterator<Item = V>, V: Into<String>>(
353 mut self,
354 enum_values: I,
355 ) -> Self {
356 self.enum_values = enum_values.into_iter().map(|value| value.into()).collect();
357 self
358 }
359}
360
361#[cfg(test)]
362mod tests {
363 use assert_json_diff::assert_json_eq;
364 use serde_json::json;
365
366 use super::*;
367
368 macro_rules! test_fn {
369 ($name:ident : $schema:expr; $expected:literal) => {
370 #[test]
371 fn $name() {
372 let value = serde_json::to_value($schema).unwrap();
373 let expected_value: serde_json::Value = serde_json::from_str($expected).unwrap();
374
375 assert_eq!(
376 value,
377 expected_value,
378 "testing serializing \"{}\": \nactual:\n{}\nexpected:\n{}",
379 stringify!($name),
380 value,
381 expected_value
382 );
383
384 println!("{}", &serde_json::to_string_pretty(&$schema).unwrap());
385 }
386 };
387 }
388
389 test_fn! {
390 create_server_with_builder_and_variable_substitution:
391 Server::new("/api/{version}/{username}")
392 .add_variable(
393 "version",
394 ServerVariable::new()
395 .enum_values(["v1", "v2"])
396 .description("api version")
397 .default_value("v1")
398 )
399 .add_variable(
400 "username",
401 ServerVariable::new().default_value("the_user")
402 );
403 r###"{
404 "url": "/api/{version}/{username}",
405 "variables": {
406 "version": {
407 "enum": ["v1", "v2"],
408 "default": "v1",
409 "description": "api version"
410 },
411 "username": {
412 "default": "the_user"
413 }
414 }
415}"###
416 }
417
418 #[test]
419 fn test_servers_is_empty() {
420 let servers = Servers::new();
421 assert!(servers.is_empty());
422 }
423
424 #[test]
425 fn test_servers_server() {
426 let servers = Servers::new();
427 let server = Server::new("/api/v1").description("api v1");
428 let servers = servers.server(server);
429 assert!(servers.len() == 1);
430 }
431
432 #[test]
433 fn test_servers_insert() {
434 let mut servers = Servers::new();
435 let server = Server::new("/api/v1").description("api v1");
436 servers.insert(server);
437 assert!(servers.len() == 1);
438 }
439
440 #[test]
441 fn test_servers_insert_existed_server() {
442 let mut servers = Servers::new();
443 let server1 = Server::new("/api/v1".to_owned())
444 .description("api v1")
445 .add_variable("key1", ServerVariable::new());
446 servers.insert(server1);
447
448 let server2 = Server::new("/api/v1".to_owned())
449 .description("api v1 new description")
450 .add_variable("key2", ServerVariable::new());
451 servers.insert(server2);
452
453 assert!(servers.len() == 1);
454 assert_json_eq!(
455 servers,
456 json!([
457 {
458 "description": "api v1 new description",
459 "url": "/api/v1",
460 "variables": {
461 "key1": {
462 "default": ""
463 },
464 "key2": {
465 "default": ""
466 }
467 }
468 }
469 ])
470 )
471 }
472
473 #[test]
474 fn test_servers_append() {
475 let mut servers = Servers::new();
476
477 let server = Server::new("/api/v1").description("api v1");
478 let mut other_servers: Servers = Servers::new();
479
480 other_servers.insert(server);
481 assert!(!other_servers.is_empty());
482
483 servers.append(&mut other_servers);
484 assert!(!servers.is_empty());
485 }
486
487 #[test]
488 fn test_servers_extend() {
489 let mut servers = Servers::new();
490
491 let server = Server::new("/api/v1").description("api v1");
492 let mut other_servers: Servers = Servers::new();
493
494 other_servers.insert(server);
495 assert!(!other_servers.is_empty());
496
497 servers.extend(other_servers);
498 assert!(!servers.is_empty());
499 }
500
501 #[test]
502 fn test_servers_deref() {
503 let mut servers = Servers::new();
504 let server = Server::new("/api/v1").description("api v1");
505 servers.insert(server);
506 assert!(servers.len() == 1);
507 assert!(servers.deref().len() == 1);
508
509 servers.deref_mut().clear();
510 assert!(servers.is_empty());
511 }
512
513 #[test]
514 fn test_server_set_url() {
515 let server = Server::new("/api/v1");
516 assert_eq!(server.url, "/api/v1");
517
518 let server = server.url("/new/api/v1");
519 assert_eq!(server.url, "/new/api/v1");
520 }
521
522 #[test]
523 fn test_server_cmp() {
524 let server_a = Server::new("/api/v1");
525 let server_b = Server::new("/api/v2");
526 assert!(server_a < server_b);
527 }
528
529 #[test]
530 fn test_server_variables_is_empty() {
531 let server_variables = ServerVariables::new();
532 assert!(server_variables.is_empty());
533 }
534
535 #[test]
536 fn test_server_variables_server_variable() {
537 let server_variables = ServerVariables::new();
538 let variable = ServerVariable::new();
539 let server_variables = server_variables.server_variable("key", variable);
540
541 assert!(!server_variables.is_empty());
542 }
543
544 #[test]
545 fn test_server_variables_insert() {
546 let mut server_variables = ServerVariables::new();
547 let variable = ServerVariable::new();
548 server_variables.insert("key", variable);
549 assert!(server_variables.len() == 1);
550
551 let new_variable = ServerVariable::new().description("description");
552 server_variables.insert("key", new_variable);
553 assert!(server_variables.len() == 1);
554 }
555
556 #[test]
557 fn test_server_variables_append() {
558 let mut server_variables = ServerVariables::new();
559
560 let mut other_server_variables = ServerVariables::new();
561 let variable = ServerVariable::new();
562 other_server_variables.insert("key", variable);
563
564 server_variables.append(&mut other_server_variables);
565 assert!(server_variables.len() == 1);
566 }
567
568 #[test]
569 fn test_server_variables_extend() {
570 let mut server_variables = ServerVariables::new();
571
572 let mut other_server_variables = ServerVariables::new();
573 let variable = ServerVariable::new();
574 other_server_variables.insert("key", variable);
575
576 server_variables.extend(other_server_variables.0);
577 assert!(server_variables.len() == 1);
578 }
579
580 #[test]
581 fn test_server_variables_deref() {
582 let mut server_variables = ServerVariables::new();
583
584 let variable = ServerVariable::new().default_value("default_value");
585 server_variables.insert("key", variable);
586
587 assert!(!server_variables.is_empty());
588 assert!(server_variables.deref().len() == 1);
589
590 server_variables.deref_mut().clear();
591 assert!(server_variables.is_empty());
592 }
593}