From 8d6313afa07ea93836890af2c877bac346d2e1b3 Mon Sep 17 00:00:00 2001
From: Konstantin Kostiuk <settydark@gmail.com>
Date: Tue, 8 Nov 2022 21:40:20 +0200
Subject: [PATCH] Add example of static-file-server using serve dir with
 handler as service (#1501)

* add example of static-file-seriver using serve dit with handler as service

* update handle return type in example

Co-authored-by: David Pedersen <david.pdrsn@gmail.com>

* cargo fmt fix

* change error mapping

Co-authored-by: David Pedersen <david.pdrsn@gmail.com>
---
 examples/static-file-server/src/main.rs | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/examples/static-file-server/src/main.rs b/examples/static-file-server/src/main.rs
index 72fc0c46..90cfc5e4 100644
--- a/examples/static-file-server/src/main.rs
+++ b/examples/static-file-server/src/main.rs
@@ -6,6 +6,7 @@
 
 use axum::{
     body::Body,
+    handler::HandlerWithoutStateExt,
     http::{Request, StatusCode},
     response::IntoResponse,
     routing::{get, get_service},
@@ -35,8 +36,9 @@ async fn main() {
         serve(using_serve_dir(), 3001),
         serve(using_serve_dir_with_assets_fallback(), 3002),
         serve(using_serve_dir_only_from_root_via_fallback(), 3003),
-        serve(two_serve_dirs(), 3004),
-        serve(calling_serve_dir_from_a_handler(), 3005),
+        serve(using_serve_dir_with_handler_as_service(), 3004),
+        serve(two_serve_dirs(), 3005),
+        serve(calling_serve_dir_from_a_handler(), 3006),
     );
 }
 
@@ -86,6 +88,24 @@ fn using_serve_dir_only_from_root_via_fallback() -> Router {
         .fallback_service(serve_dir)
 }
 
+fn using_serve_dir_with_handler_as_service() -> Router {
+    async fn handle_404() -> (StatusCode, &'static str) {
+        (StatusCode::NOT_FOUND, "Not found")
+    }
+
+    // you can convert handler function to service
+    let service = handle_404
+        .into_service()
+        .map_err(|err| -> std::io::Error { match err {} });
+
+    let serve_dir = ServeDir::new("assets").not_found_service(service);
+    let serve_dir = get_service(serve_dir).handle_error(handle_error);
+
+    Router::new()
+        .route("/foo", get(|| async { "Hi from /foo" }))
+        .fallback_service(serve_dir)
+}
+
 fn two_serve_dirs() -> Router {
     // you can also have two `ServeDir`s nested at different paths
     let serve_dir_from_assets = get_service(ServeDir::new("assets")).handle_error(handle_error);