1pub mod core;
2
3use std::net::SocketAddr;
4use actix_web::{web::ServiceConfig, HttpServer};
5use hashira::{adapter::Adapter, app::AppService};
6
7#[derive(Clone)]
9pub struct HashiraActixWeb<F = ()>(F);
10
11impl HashiraActixWeb<()> {
12 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 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 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 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}