hashira_actix_web/
lib.rs

1pub mod core;
2
3use std::net::SocketAddr;
4use actix_web::{web::ServiceConfig, HttpServer};
5use hashira::{adapter::Adapter, app::AppService};
6
7/// An adapter for `actix-web`.
8#[derive(Clone)]
9pub struct HashiraActixWeb<F = ()>(F);
10
11impl HashiraActixWeb<()> {
12    /// Constructs an adapter without any configuration.
13    pub fn new() -> HashiraActixWeb<()> {
14        HashiraActixWeb(())
15    }
16}
17
18impl Default for HashiraActixWeb<()> {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24#[hashira::async_trait]
25impl<F> Adapter for HashiraActixWeb<F>
26where
27    F: sealed::ConfigureActixService + Send + Clone + 'static,
28{
29    /// Starts the server.
30    async fn serve(self, app: AppService) -> Result<(), hashira::error::BoxError> {
31        let host = hashira::env::get_host().unwrap_or_else(|| String::from("127.0.0.1"));
32        let port = hashira::env::get_port().unwrap_or(5000);
33        let addr: SocketAddr = format!("{host}:{port}").as_str().parse().unwrap();
34
35        println!("Server started at: http://{addr}");
36
37        // Create and run the server
38        let server = HttpServer::new(move || {
39            let config = self.0.clone();
40            actix_web::App::new()
41                .configure(move |cfg| config.configure(cfg))
42                .configure(core::router(app.clone()))
43        })
44        .bind(addr)?
45        .run();
46
47        // Awaits
48        server.await?;
49
50        Ok(())
51    }
52}
53
54impl<F> From<F> for HashiraActixWeb<F>
55where
56    F: sealed::ConfigureActixService + Send + Clone + 'static,
57{
58    fn from(value: F) -> Self {
59        HashiraActixWeb(value)
60    }
61}
62
63impl<F> sealed::ConfigureActixService for F
64where
65    F: FnOnce(&mut ServiceConfig) + Send + Clone + 'static,
66{
67    fn configure(self, config: &mut ServiceConfig) {
68        (self)(config)
69    }
70}
71
72impl sealed::ConfigureActixService for () {
73    fn configure(self, _: &mut ServiceConfig) {}
74}
75
76#[doc(hidden)]
77pub(crate) mod sealed {
78    use actix_web::web::ServiceConfig;
79
80    pub trait ConfigureActixService {
81        fn configure(self, config: &mut ServiceConfig);
82    }
83}