1+ use axum:: response:: { Html , Redirect } ;
12use std:: { net:: SocketAddr , sync:: Arc } ;
3+ use utoipa:: OpenApi ;
4+ use utoipa_swagger_ui:: SwaggerUi ;
25
3- use axum:: body:: HttpBody ;
4- use axum:: routing:: MethodRouter ;
56use axum:: { routing:: get, Router } ;
7+ use tokio:: net:: TcpListener ;
68use tokio_util:: sync:: CancellationToken ;
79use tower_http:: cors:: CorsLayer ;
810use tower_http:: trace:: TraceLayer ;
911use tracing:: info;
10- use utoipa:: OpenApi ;
11- use utoipa_swagger_ui:: SwaggerUi ;
1212
13- use crate :: models:: bulk:: { BulkResponse , ListResponse } ;
14- use crate :: models:: error:: ErrorResponse ;
15- use crate :: models:: profile:: ENSProfile ;
1613use crate :: routes;
1714use crate :: state:: AppState ;
1815
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-
2616pub struct App {
2717 router : Router ,
2818}
@@ -35,11 +25,14 @@ impl App {
3525 ) -> Result < ( ) , anyhow:: Error > {
3626 let addr = SocketAddr :: from ( ( [ 0 , 0 , 0 , 0 ] , port) ) ;
3727
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) ) ;
4336
4437 info ! ( "Listening HTTP on {}" , addr) ;
4538
@@ -53,19 +46,24 @@ impl App {
5346
5447pub fn setup ( state : AppState ) -> App {
5548 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) )
6967 . fallback ( routes:: four_oh_four:: handler)
7068 . layer ( CorsLayer :: permissive ( ) )
7169 . layer ( TraceLayer :: new_for_http ( ) )
@@ -74,21 +72,8 @@ pub fn setup(state: AppState) -> App {
7472 App { router }
7573}
7674
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)
9479}
0 commit comments