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