1use crate::error::CliError;
17
18pub fn execute_route_list(format: &str) -> Result<(), CliError> {
24 let routes = collect_routes();
25
26 match format {
27 "table" => print_table(&routes),
28 "json" => print_json(&routes)?,
29 _ => {
30 return Err(CliError::Generic(format!(
31 "Unsupported format: {} (supported: table, json)",
32 format
33 )));
34 }
35 }
36
37 Ok(())
38}
39
40#[derive(Debug, Clone)]
42pub struct RouteInfo {
43 pub method: &'static str,
45 pub path: &'static str,
47 pub app: &'static str,
49 pub controller: &'static str,
51 pub action: &'static str,
53}
54
55pub fn collect_routes() -> Vec<RouteInfo> {
57 vec![
58 RouteInfo {
59 method: "GET",
60 path: "/",
61 app: "index",
62 controller: "Index",
63 action: "index",
64 },
65 RouteInfo {
66 method: "GET",
67 path: "/oapc/customer/index",
68 app: "oapc",
69 controller: "Customer",
70 action: "index",
71 },
72 RouteInfo {
73 method: "GET",
74 path: "/admin/user/list",
75 app: "admin",
76 controller: "User",
77 action: "list",
78 },
79 RouteInfo {
80 method: "GET",
81 path: "/api/goods/list",
82 app: "api",
83 controller: "Goods",
84 action: "list",
85 },
86 RouteInfo {
87 method: "POST",
88 path: "/api/order/save",
89 app: "api",
90 controller: "Order",
91 action: "save",
92 },
93 RouteInfo {
94 method: "GET",
95 path: "/farm/weight/index",
96 app: "farm",
97 controller: "Weight",
98 action: "index",
99 },
100 RouteInfo {
101 method: "GET",
102 path: "/cashier/order/index",
103 app: "cashier",
104 controller: "Order",
105 action: "index",
106 },
107 RouteInfo {
108 method: "GET",
109 path: "/scene/device/index",
110 app: "scene",
111 controller: "Device",
112 action: "index",
113 },
114 ]
115}
116
117fn print_table(routes: &[RouteInfo]) {
119 println!(
120 "{:<6} {:<25} {:<8} {:<12} {:<10}",
121 "Method", "Path", "App", "Controller", "Action"
122 );
123 println!("{}", "-".repeat(70));
124
125 for route in routes {
126 println!(
127 "{:<6} {:<25} {:<8} {:<12} {:<10}",
128 route.method, route.path, route.app, route.controller, route.action
129 );
130 }
131
132 println!();
133 println!("Registered apps: oapc, admin, api, farm, oapi, cashier, scene");
134 println!("Default app: index | Default controller: Index | Default action: index");
135}
136
137fn print_json(routes: &[RouteInfo]) -> Result<(), CliError> {
139 let json: Vec<serde_json::Value> = routes
140 .iter()
141 .map(|r| {
142 serde_json::json!({
143 "method": r.method,
144 "path": r.path,
145 "app": r.app,
146 "controller": r.controller,
147 "action": r.action,
148 })
149 })
150 .collect();
151
152 let output = serde_json::to_string_pretty(&json)
153 .map_err(|e| CliError::Generic(format!("JSON serialization failed: {}", e)))?;
154 println!("{}", output);
155 Ok(())
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161
162 #[test]
163 fn test_execute_route_list_table_format() {
164 let result = execute_route_list("table");
165 assert!(result.is_ok());
166 }
167
168 #[test]
169 fn test_execute_route_list_json_format() {
170 let result = execute_route_list("json");
171 assert!(result.is_ok());
172 }
173
174 #[test]
175 fn test_execute_route_list_invalid_format() {
176 let result = execute_route_list("xml");
177 assert!(matches!(result, Err(CliError::Generic(_))));
178 }
179
180 #[test]
181 fn test_collect_routes_not_empty() {
182 let routes = collect_routes();
183 assert!(!routes.is_empty());
184 }
185
186 #[test]
187 fn test_collect_routes_contains_default_route() {
188 let routes = collect_routes();
189 assert!(routes.iter().any(|r| r.path == "/" && r.app == "index"));
190 }
191
192 #[test]
193 fn test_collect_routes_contains_all_apps() {
194 let routes = collect_routes();
195 let apps: Vec<&str> = routes.iter().map(|r| r.app).collect();
196 assert!(apps.contains(&"oapc"));
197 assert!(apps.contains(&"admin"));
198 assert!(apps.contains(&"api"));
199 assert!(apps.contains(&"farm"));
200 assert!(apps.contains(&"cashier"));
201 assert!(apps.contains(&"scene"));
202 }
203
204 #[test]
205 fn test_print_table_does_not_panic() {
206 let routes = collect_routes();
207 print_table(&routes);
208 }
209
210 #[test]
211 fn test_print_json_valid_json() {
212 let routes = collect_routes();
213 let result = std::panic::catch_unwind(|| print_json(&routes));
214 assert!(result.is_ok());
215 }
216}