web_server_abstraction/adapters/
mock.rs1use crate::core::{HandlerFn, Middleware};
4use crate::error::{Result, WebServerError};
5use crate::types::{HttpMethod, Request, Response, StatusCode};
6use std::collections::HashMap;
7
8pub struct MockAdapter {
10 routes: HashMap<(String, HttpMethod), HandlerFn>,
11 middleware: Vec<Box<dyn Middleware>>,
12 addr: Option<String>,
13 running: bool,
14}
15
16impl Default for MockAdapter {
17 fn default() -> Self {
18 Self::new()
19 }
20}
21
22impl MockAdapter {
23 pub fn new() -> Self {
24 Self {
25 routes: HashMap::new(),
26 middleware: Vec::new(),
27 addr: None,
28 running: false,
29 }
30 }
31
32 pub async fn bind(&mut self, addr: &str) -> Result<()> {
34 self.addr = Some(addr.to_string());
35 println!("Mock server bound to {}", addr);
36 Ok(())
37 }
38
39 pub async fn run(mut self) -> Result<()> {
41 let addr = self
42 .addr
43 .ok_or_else(|| WebServerError::bind_error("No address bound"))?;
44
45 self.running = true;
46 println!(
47 "Mock server running on {} with {} routes",
48 addr,
49 self.routes.len()
50 );
51
52 println!("Mock server would run indefinitely here...");
55
56 Ok(())
57 }
58
59 pub fn route(&mut self, path: &str, method: HttpMethod, handler: HandlerFn) -> &mut Self {
61 let route_key = (path.to_string(), method);
62 self.routes.insert(route_key, handler);
63 println!("Added route: {:?} {}", method, path);
64 self
65 }
66
67 pub fn middleware(&mut self, middleware: Box<dyn Middleware>) -> &mut Self {
69 self.middleware.push(middleware);
70 println!("Added middleware");
71 self
72 }
73
74 pub async fn simulate_request(&self, method: HttpMethod, path: &str) -> Result<Response> {
76 let route_key = (path.to_string(), method);
77
78 if let Some(handler) = self.routes.get(&route_key) {
79 let request = Request::new(method, path.parse().unwrap());
80 handler(request).await
81 } else {
82 Ok(Response::new(StatusCode::NOT_FOUND).body("Route not found"))
83 }
84 }
85
86 pub fn is_running(&self) -> bool {
87 self.running
88 }
89
90 pub fn get_bound_address(&self) -> Option<&String> {
91 self.addr.as_ref()
92 }
93}