1use super::*;
2use serde_json::Value;
3use std::collections::HashSet;
4use std::fmt;
5
6#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
7pub struct EpForTable {
8 pub path: String,
9 servers: Vec<String>,
11 pub ops: Vec<Method>,
12 pub query_params: Vec<String>,
13 pub headers_params: Vec<String>,
14 pub req_body_params: Vec<String>,
15 pub res_params: Vec<String>,
16 pub statuses: Vec<String>,
17}
18impl fmt::Display for EpForTable {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 let mut string = String::new();
21 let lines = *([
22 self.statuses.len(),
23 self.ops.len(),
24 self.query_params.len(),
25 self.req_body_params.len(),
26 self.headers_params.len(),
27 self.res_params.len(),
28 ]
29 .iter()
30 .max()
31 .unwrap_or(&0));
32 let h_p = vv(&self.headers_params, 0);
33 let h_p = &h_p[0..*([h_p.len(), 25].iter().min().unwrap_or(&0))];
34 let q_p = vv(&self.query_params, 0);
35 let q_p = &q_p[0..*([q_p.len(), 25].iter().min().unwrap_or(&0))];
36 let r_b_p = vv(&self.req_body_params, 0);
37 let r_b_p = &r_b_p[0..*([r_b_p.len(), 25].iter().min().unwrap_or(&0))];
38 let r_p = vv(&self.res_params, 0);
39 let r_p = &r_p[0..*([r_p.len(), 25].iter().min().unwrap_or(&0))];
40 string.push_str(&format!(
41 "{:75}|{:7}|{:25}|{:25}|{:25}|{:25}|{:8}\n",
42 &self.path.bold().bright_cyan(),
43 vv(&self.ops, 0),
44 q_p,
45 h_p,
46 r_b_p,
47 r_p,
48 color_status(&vv(&self.statuses, 0))
49 ));
50 for i in 1..lines {
51 let h_p = vv(&self.headers_params, i);
52 let h_p = &h_p[0..*([h_p.len(), 25].iter().min().unwrap_or(&0))];
53 let q_p = vv(&self.query_params, i);
54 let q_p = &q_p[0..*([q_p.len(), 25].iter().min().unwrap_or(&0))];
55 let r_b_p = vv(&self.req_body_params, i);
56 let r_b_p = &r_b_p[0..*([r_b_p.len(), 25].iter().min().unwrap_or(&0))];
57 let r_p = vv(&self.res_params, i);
58 let r_p = &r_p[0..*([r_p.len(), 25].iter().min().unwrap_or(&0))];
59 string.push_str(&format!(
60 "{:75}|{:7}|{:25}|{:25}|{:25}|{:25}|{:8}\n",
61 "",
62 vv(&self.ops, i),
63 q_p,
64 h_p,
65 r_b_p,
66 r_p,
67 color_status(&vv(&self.statuses, i))
68 ));
69 }
70 string.push_str(&format!("{:-<200}\n", ""));
71 write!(f, "{}", string)
72 }
73}
74impl EpForTable {
75 fn get_all_possible_schemas(schema: &Schema) -> Vec<SchemaRef> {
76 let mut schemas = vec![];
77 if let Some(items) = schema.items.clone() {
78 schemas.push(*items);
79 }
80 if let Some(any) = schema.any_of.clone() {
81 schemas.extend(any);
82 }
83 if let Some(all) = schema.all_of.clone() {
84 schemas.extend(all);
85 }
86 if let Some(one) = schema.one_of.clone() {
87 schemas.extend(one);
88 }
89 schemas
90 }
91 fn get_props(schema: &Schema) -> HashMap<String, SchemaRef> {
92 if let Some(props) = schema.properties.clone() {
93 props
94 } else {
95 HashMap::new()
96 }
97 }
98 fn get_name_s_ref(s_ref: &SchemaRef, value: &Value, name: Option<&String>) -> String {
99 let schema = s_ref.inner(value);
100 if let Some(ref t) = schema.title {
101 t.to_string()
102 } else if let SchemaRef::Ref(r) = s_ref {
103 r.param_ref.split('/').last().unwrap().to_string()
104 } else if let Some(n) = name {
105 n.to_string()
106 } else {
107 String::new()
108 }
109 }
110 fn schema_rec(
111 params: &mut HashSet<String>,
112 schema_ref: &SchemaRef,
113 value: &Value,
114 name_f: Option<&String>,
115 ) {
116 let schema = schema_ref.inner(value);
117 for s in Self::get_all_possible_schemas(&schema) {
118 let n = Self::get_name_s_ref(schema_ref, value, name_f);
119 Self::schema_rec(params, &s, value, Some(&n));
120 params.insert(n);
121 }
122 for (n, prop) in Self::get_props(&schema) {
123 Self::schema_rec(params, &prop, value, Some(&n));
124 params.insert(n);
125 }
126 }
127 pub fn from_oas_path(path: &str, item: &PathItem, value: &Value) -> Self {
128 let ops1 = item.get_ops();
129 let (mut query_params, mut headers_params, mut req_body_params, mut res_params): (
131 Vec<String>,
132 Vec<String>,
133 Vec<String>,
134 Vec<String>,
135 ) = (vec![], vec![], vec![], vec![]);
136 for (_, op) in ops1.iter() {
137 let q: Vec<String> = op
138 .params()
139 .iter()
140 .filter_map(|param| {
141 let param = param.inner(value);
142 match param.from() {
143 QuePay::Query => Some(param.name),
144 _ => None,
145 }
146 })
147 .collect();
148 let h: Vec<String> = op
149 .params()
150 .iter()
151 .filter_map(|param| {
152 let param = param.inner(value);
153 match param.from() {
154 QuePay::Headers => Some(param.name),
155 _ => None,
156 }
157 })
158 .collect();
159 let req: Vec<String> = if let Some(b) = &op.request_body {
160 let mut params = HashSet::new();
161 for m_t in b.inner(value).content.values() {
162 if let Some(schema) = &m_t.schema {
163 Self::schema_rec(&mut params, schema, value, None);
164 }
165 }
166 params.iter().cloned().collect::<Vec<String>>()
167 } else {
168 vec![]
169 };
170 let res: Vec<String> = op
171 .responses()
172 .iter()
173 .flat_map(|(_, payload)| {
174 let mut params = HashSet::new();
175 if let Some(c) = &payload.inner(value).content {
176 for m_t in c.values() {
177 if let Some(schema) = &m_t.schema {
178 Self::schema_rec(&mut params, schema, value, None);
179 }
180 }
181 }
182 params.iter().cloned().collect::<Vec<String>>()
183 })
184 .collect();
185 query_params.extend(q);
186 headers_params.extend(h);
187 req_body_params.extend(req);
188 res_params.extend(res);
189 }
190 EpForTable {
191 path: path.to_string(),
192 servers: item
193 .servers
194 .as_ref()
195 .unwrap_or(&vec![])
196 .iter()
197 .map(|s| s.base_url.clone())
198 .collect(),
199 ops: ops1.iter().map(|(m, _)| m).cloned().collect(),
200 query_params,
201 headers_params,
202 statuses: ops1
203 .iter()
204 .flat_map(|(_, op)| {
205 op.responses
206 .as_ref()
207 .unwrap_or(&HashMap::new())
208 .iter()
209 .map(|(s, _)| s)
210 .cloned()
211 .collect::<Vec<String>>()
212 })
213 .collect(),
214 res_params,
215 req_body_params,
216 }
217 }
218}
219#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
220pub struct EpTable {
221 pub eps: Vec<EpForTable>,
222 servers: Vec<String>,
223}
224impl EpTable {
225 pub fn print(&self) {
226 let head = format!(
227 "{:75}|{:7}|{:25}|{:25}|{:25}|{:25}|{:8}",
228 "PATH".bold().underline(),
229 "METHODS".bold().underline(),
230 "QUERY PARAMS".bold().underline(),
231 "HEADER PARAMS".bold().underline(),
232 "BODY_PARAMS".bold().underline(),
233 "RESPONSE PARAMS".bold().underline(),
234 "STATUSES".bold().underline()
235 );
236 for (i, ep) in self.eps.iter().enumerate() {
237 if i % 50usize == 0 {
238 println!("{}\n{:-<190}", head, "");
239 }
240 print!("{}", ep);
241 }
242 }
244 pub fn path_only(&self, path: &str) -> Self {
245 let eps = self
246 .eps
247 .iter()
248 .filter(|p| p.path.as_str() == path)
249 .cloned()
250 .collect::<Vec<EpForTable>>();
251 EpTable {
252 servers: self.servers.clone(),
253 eps,
254 }
255 }
256 pub fn new<T>(value: &Value) -> Self
257 where
258 T: OAS + Clone + Serialize + for<'de> serde::Deserialize<'de>,
259 {
260 let oas = serde_json::from_value::<T>(value.clone()).unwrap();
261 let eps: Vec<EpForTable> = oas
262 .get_paths()
263 .iter()
264 .map(|(path, item)| EpForTable::from_oas_path(path, item, value))
265 .collect();
266 EpTable {
267 eps,
268 servers: oas
269 .servers()
270 .as_ref()
271 .unwrap_or(&vec![])
272 .iter()
273 .map(|s| s.base_url.clone())
274 .collect(),
275 }
276 }
277}