1
+ use axum:: response:: { Html , Redirect } ;
1
2
use std:: { net:: SocketAddr , sync:: Arc } ;
3
+ use utoipa:: OpenApi ;
4
+ use utoipa_swagger_ui:: SwaggerUi ;
2
5
3
- use axum:: body:: HttpBody ;
4
- use axum:: routing:: MethodRouter ;
5
6
use axum:: { routing:: get, Router } ;
7
+ use tokio:: net:: TcpListener ;
6
8
use tokio_util:: sync:: CancellationToken ;
7
9
use tower_http:: cors:: CorsLayer ;
8
10
use tower_http:: trace:: TraceLayer ;
9
11
use tracing:: info;
10
- use utoipa:: OpenApi ;
11
- use utoipa_swagger_ui:: SwaggerUi ;
12
12
13
- use crate :: models:: bulk:: { BulkResponse , ListResponse } ;
14
- use crate :: models:: error:: ErrorResponse ;
15
- use crate :: models:: profile:: ENSProfile ;
16
13
use crate :: routes;
17
14
use crate :: state:: AppState ;
18
15
19
- #[ derive( OpenApi ) ]
20
- #[ openapi(
21
- paths( routes:: address:: get, routes:: name:: get, routes:: universal:: get) ,
22
- components( schemas( ENSProfile , ListResponse <BulkResponse <ENSProfile >>, ErrorResponse ) )
23
- ) ]
24
- pub struct ApiDoc ;
25
-
26
16
pub struct App {
27
17
router : Router ,
28
18
}
@@ -35,11 +25,14 @@ impl App {
35
25
) -> Result < ( ) , anyhow:: Error > {
36
26
let addr = SocketAddr :: from ( ( [ 0 , 0 , 0 , 0 ] , port) ) ;
37
27
38
- let server = axum:: Server :: try_bind ( & addr) ?
39
- . serve ( self . router . into_make_service ( ) )
40
- . with_graceful_shutdown ( async {
41
- shutdown_signal. cancelled ( ) . await ;
42
- } ) ;
28
+ let listener = TcpListener :: bind ( & addr) . await ?;
29
+
30
+ async fn await_shutdown ( shutdown_signal : CancellationToken ) {
31
+ shutdown_signal. cancelled ( ) . await ;
32
+ }
33
+
34
+ let server = axum:: serve ( listener, self . router . into_make_service ( ) )
35
+ . with_graceful_shutdown ( await_shutdown ( shutdown_signal) ) ;
43
36
44
37
info ! ( "Listening HTTP on {}" , addr) ;
45
38
@@ -53,19 +46,24 @@ impl App {
53
46
54
47
pub fn setup ( state : AppState ) -> App {
55
48
let router = Router :: new ( )
56
- . merge ( SwaggerUi :: new ( "/docs" ) . url ( "/docs/openapi.json" , ApiDoc :: openapi ( ) ) )
57
- . route ( "/" , get ( routes:: root:: get) )
58
- . directory_route ( "/a/:address" , get ( routes:: address:: get) )
59
- . directory_route ( "/n/:name" , get ( routes:: name:: get) )
60
- . directory_route ( "/u/:name_or_address" , get ( routes:: universal:: get) )
61
- . directory_route ( "/i/:name_or_address" , get ( routes:: image:: get) )
62
- . directory_route ( "/h/:name_or_address" , get ( routes:: header:: get) )
63
- . directory_route ( "/bulk/a" , get ( routes:: address:: get_bulk) )
64
- . directory_route ( "/bulk/n" , get ( routes:: name:: get_bulk) )
65
- . directory_route ( "/bulk/u" , get ( routes:: universal:: get_bulk) )
66
- . directory_route ( "/sse/a" , get ( routes:: address:: get_bulk_sse) )
67
- . directory_route ( "/sse/n" , get ( routes:: name:: get_bulk_sse) )
68
- . directory_route ( "/sse/u" , get ( routes:: universal:: get_bulk_sse) )
49
+ . route (
50
+ "/" ,
51
+ get ( || async { Redirect :: temporary ( "/docs" ) } ) ,
52
+ )
53
+ . route ( "/docs" , get ( scalar_handler) )
54
+ . route ( "/docs/openapi.json" , get ( crate :: docs:: openapi) )
55
+ . route ( "/this" , get ( routes:: root:: get) )
56
+ . route ( "/a/:address" , get ( routes:: address:: get) )
57
+ . route ( "/n/:name" , get ( routes:: name:: get) )
58
+ . route ( "/u/:name_or_address" , get ( routes:: universal:: get) )
59
+ . route ( "/i/:name_or_address" , get ( routes:: image:: get) )
60
+ . route ( "/h/:name_or_address" , get ( routes:: header:: get) )
61
+ . route ( "/bulk/a" , get ( routes:: address:: get_bulk) )
62
+ . route ( "/bulk/n" , get ( routes:: name:: get_bulk) )
63
+ . route ( "/bulk/u" , get ( routes:: universal:: get_bulk) )
64
+ . route ( "/sse/a" , get ( routes:: address:: get_bulk_sse) )
65
+ . route ( "/sse/n" , get ( routes:: name:: get_bulk_sse) )
66
+ . route ( "/sse/u" , get ( routes:: universal:: get_bulk_sse) )
69
67
. fallback ( routes:: four_oh_four:: handler)
70
68
. layer ( CorsLayer :: permissive ( ) )
71
69
. layer ( TraceLayer :: new_for_http ( ) )
@@ -74,21 +72,8 @@ pub fn setup(state: AppState) -> App {
74
72
App { router }
75
73
}
76
74
77
- trait RouterExt < S , B >
78
- where
79
- B : HttpBody + Send + ' static ,
80
- S : Clone + Send + Sync + ' static ,
81
- {
82
- fn directory_route ( self , path : & str , method_router : MethodRouter < S , B > ) -> Self ;
83
- }
84
-
85
- impl < S , B > RouterExt < S , B > for Router < S , B >
86
- where
87
- B : HttpBody + Send + ' static ,
88
- S : Clone + Send + Sync + ' static ,
89
- {
90
- fn directory_route ( self , path : & str , method_router : MethodRouter < S , B > ) -> Self {
91
- self . route ( path, method_router. clone ( ) )
92
- . route ( & format ! ( "{path}/" ) , method_router)
93
- }
75
+ // Loads from docs/index.html with headers html
76
+ async fn scalar_handler ( ) -> Html < & ' static str > {
77
+ let contents = include_str ! ( "./docs/index.html" ) ;
78
+ axum:: response:: Html ( contents)
94
79
}
0 commit comments