web_server_abstraction/adapters/
mock.rs

1//! Mock adapter for testing and demonstration purposes.
2
3use crate::core::{HandlerFn, Middleware};
4use crate::error::{Result, WebServerError};
5use crate::types::{HttpMethod, Request, Response, StatusCode};
6use std::collections::HashMap;
7
8/// Mock web server adapter for testing
9pub 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    /// Bind the server to an address
33    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    /// Run the server
40    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        // In a real server, this would be an infinite loop handling requests
53        // For the mock, we'll just simulate that it's running
54        println!("Mock server would run indefinitely here...");
55
56        Ok(())
57    }
58
59    /// Add a route to the server
60    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    /// Add middleware to the server
68    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    /// Simulate a request for testing
75    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}