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