1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct SwaggerInfo {
11 pub title: String,
12 pub version: String,
13 pub description: String,
14}
15
16#[allow(dead_code)]
18#[derive(Debug, Clone)]
19pub struct SwaggerOperation {
20 pub path: String,
21 pub method: String,
22 pub summary: String,
23 pub tags: Vec<String>,
24}
25
26#[allow(dead_code)]
28#[derive(Debug, Clone)]
29pub struct SwaggerDoc {
30 pub info: SwaggerInfo,
31 pub host: String,
32 pub base_path: String,
33 pub operations: Vec<SwaggerOperation>,
34}
35
36#[allow(dead_code)]
38pub fn new_swagger_doc(title: &str, version: &str, host: &str) -> SwaggerDoc {
39 SwaggerDoc {
40 info: SwaggerInfo {
41 title: title.to_string(),
42 version: version.to_string(),
43 description: String::new(),
44 },
45 host: host.to_string(),
46 base_path: "/".to_string(),
47 operations: Vec::new(),
48 }
49}
50
51#[allow(dead_code)]
53pub fn add_operation(doc: &mut SwaggerDoc, path: &str, method: &str, summary: &str) {
54 doc.operations.push(SwaggerOperation {
55 path: path.to_string(),
56 method: method.to_string(),
57 summary: summary.to_string(),
58 tags: Vec::new(),
59 });
60}
61
62#[allow(dead_code)]
64pub fn add_tag(doc: &mut SwaggerDoc, tag: &str) {
65 if let Some(op) = doc.operations.last_mut() {
66 op.tags.push(tag.to_string());
67 }
68}
69
70#[allow(dead_code)]
72pub fn export_swagger_json(doc: &SwaggerDoc) -> String {
73 let mut paths = String::new();
74 for (i, op) in doc.operations.iter().enumerate() {
75 let tags: Vec<String> = op.tags.iter().map(|t| format!("\"{}\"", t)).collect();
76 let entry = format!(
77 r#""{}":{{"{}": {{"summary":"{}","tags":[{}]}}}}"#,
78 op.path,
79 op.method,
80 op.summary,
81 tags.join(",")
82 );
83 if i > 0 {
84 paths.push(',');
85 }
86 paths.push_str(&entry);
87 }
88 format!(
89 r#"{{"swagger":"2.0","info":{{"title":"{}","version":"{}"}},"host":"{}","basePath":"{}","paths":{{{}}}}}"#,
90 doc.info.title, doc.info.version, doc.host, doc.base_path, paths
91 )
92}
93
94#[allow(dead_code)]
96pub fn operation_count(doc: &SwaggerDoc) -> usize {
97 doc.operations.len()
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn new_doc_title() {
106 let doc = new_swagger_doc("My API", "1.0", "api.example.com");
107 assert_eq!(doc.info.title, "My API");
108 }
109
110 #[test]
111 fn new_doc_host() {
112 let doc = new_swagger_doc("API", "1.0", "localhost:8080");
113 assert_eq!(doc.host, "localhost:8080");
114 }
115
116 #[test]
117 fn add_operation_count() {
118 let mut doc = new_swagger_doc("API", "1.0", "host");
119 add_operation(&mut doc, "/pets", "get", "List pets");
120 assert_eq!(operation_count(&doc), 1);
121 }
122
123 #[test]
124 fn export_contains_swagger_version() {
125 let doc = new_swagger_doc("API", "1.0", "host");
126 let s = export_swagger_json(&doc);
127 assert!(s.contains("\"2.0\""));
128 }
129
130 #[test]
131 fn export_contains_title() {
132 let doc = new_swagger_doc("PetStore", "1.0", "host");
133 let s = export_swagger_json(&doc);
134 assert!(s.contains("PetStore"));
135 }
136
137 #[test]
138 fn export_contains_path() {
139 let mut doc = new_swagger_doc("API", "1.0", "host");
140 add_operation(&mut doc, "/pets", "get", "List");
141 let s = export_swagger_json(&doc);
142 assert!(s.contains("/pets"));
143 }
144
145 #[test]
146 fn add_tag_stored() {
147 let mut doc = new_swagger_doc("API", "1.0", "host");
148 add_operation(&mut doc, "/pets", "get", "List");
149 add_tag(&mut doc, "pets");
150 assert_eq!(doc.operations[0].tags.len(), 1);
151 }
152
153 #[test]
154 fn tag_in_export() {
155 let mut doc = new_swagger_doc("API", "1.0", "host");
156 add_operation(&mut doc, "/pets", "get", "List");
157 add_tag(&mut doc, "pets");
158 let s = export_swagger_json(&doc);
159 assert!(s.contains("pets"));
160 }
161
162 #[test]
163 fn add_tag_no_operations_safe() {
164 let mut doc = new_swagger_doc("API", "1.0", "host");
165 add_tag(&mut doc, "safe");
166 assert_eq!(operation_count(&doc), 0);
167 }
168
169 #[test]
170 fn base_path_default() {
171 let doc = new_swagger_doc("API", "1.0", "host");
172 assert_eq!(doc.base_path, "/");
173 }
174}