1use std::time::Instant;
9use axeon::{Server, Request, Response, Router, ServerError, ok_json};
10use axeon::middleware::{Middleware, MiddlewareResult, Next};
11
12struct Logger;
14
15impl Middleware for Logger {
16 fn call(&self, req: Request, next: Next) -> MiddlewareResult {
17 Box::pin(async move {
18 let start = Instant::now();
19 let url = req.path.clone();
20 let method = req.method.clone();
21 let res = next.handle(req).await;
22 let status = match &res {
23 Ok(res) => res.status,
24 Err(err) => err.status_code(),
25 };
26 let duration = start.elapsed().as_millis();
27 println!("[{}] {:?} {} - {}ms", status, method, url, duration);
28 res
29 })
30 }
31
32 fn clone_box(&self) -> Box<dyn Middleware> {
33 Box::new(Self)
34 }
35}
36
37struct AuthMiddleware;
39
40impl Middleware for AuthMiddleware {
41 fn call(&self, req: Request, next: Next) -> MiddlewareResult {
42 Box::pin(async move {
43 match req.get_header("Authorization") {
45 Some(token) if token.starts_with("Bearer ") => next.handle(req).await,
46 _ => Err(ServerError::Unauthorized("Authentication required".to_string())),
47 }
48 })
49 }
50
51
52 fn clone_box(&self) -> Box<dyn Middleware> {
53 Box::new(Self)
54 }
55}
56
57fn main() {
58 let mut app = Server::new();
59
60 app.middleware(Logger);
62
63 app.get("/public", |_req| async {
65 Response::text("This is a public endpoint")
66 });
67
68 let mut protected = Router::new();
70 protected.middleware(AuthMiddleware);
71
72 protected.get("/profile", |_req| async {
73 ok_json!({
74 "name": "User",
75 "email": "user@example.com"
76 })
77 });
78
79 app.mount("/api", protected);
80
81 app.listen("127.0.0.1:3000")
82 .expect("Server failed to start");
83}