small_router_layers/
small-router-layers.rs

1/*
2 * Copyright (c) 2025 Bastiaan van der Plaat
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7//! A simple small-router example with context
8
9use std::net::{Ipv4Addr, TcpListener};
10
11use small_http::{Method, Request, Response, Status};
12use small_router::RouterBuilder;
13
14#[derive(Clone)]
15struct Context {
16    data: String,
17}
18
19fn cors_pre_layer(req: &Request, _: &mut Context) -> Option<Response> {
20    if req.method == Method::Options {
21        Some(
22            Response::with_header("Access-Control-Allow-Origin", "*")
23                .header("Access-Control-Allow-Methods", "GET, POST")
24                .header("Access-Control-Max-Age", "86400"),
25        )
26    } else {
27        None
28    }
29}
30
31fn cors_post_layer(_: &Request, _: &mut Context, res: Response) -> Response {
32    res.header("Access-Control-Allow-Origin", "*")
33        .header("Access-Control-Allow-Methods", "GET, POST")
34        .header("Access-Control-Max-Age", "86400")
35}
36
37fn home(_req: &Request, ctx: &Context) -> Response {
38    println!("{}", ctx.data);
39    Response::with_body("Home")
40}
41
42fn about(_req: &Request, ctx: &Context) -> Response {
43    println!("{}", ctx.data);
44    Response::with_body("About")
45}
46
47fn not_found(_req: &Request, _ctx: &Context) -> Response {
48    Response::with_status(Status::NotFound).body("404 Not Found")
49}
50
51fn main() {
52    let ctx = Context {
53        data: "Data".to_string(),
54    };
55    let router = RouterBuilder::with(ctx)
56        .pre_layer(cors_pre_layer)
57        .post_layer(cors_post_layer)
58        .get("/", home)
59        .get("/about", about)
60        .fallback(not_found)
61        .build();
62
63    let listener = TcpListener::bind((Ipv4Addr::LOCALHOST, 8080))
64        .unwrap_or_else(|_| panic!("Can't bind to port"));
65    small_http::serve(listener, move |req| router.handle(req));
66}