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