From 43375bcb875a31ce8c6132ce78552d45f64b261b Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 17 Jun 2025 01:22:54 -0400 Subject: Use a fluent style for the middleware layers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For endpoints that are unavailable, that default behaviour no longer needs to be specified: `Required(app)` will do that for you. For endpoints that are redirects until setup is completed, `Require(app).with_fallback(…response…)` will do that. To make this a bit harder to break by accident, the default unavailable response is now its own type. --- src/setup/required.rs | 53 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'src/setup/required.rs') diff --git a/src/setup/required.rs b/src/setup/required.rs index 5b7fe5b..2112e4b 100644 --- a/src/setup/required.rs +++ b/src/setup/required.rs @@ -5,34 +5,40 @@ use axum::{ }; use std::pin::Pin; use std::task::{Context, Poll}; -use tower::Service; +use tower::{Layer, Service}; use crate::{app::App, error::Internal}; -const UNAVAILABLE: (StatusCode, &str) = ( - StatusCode::SERVICE_UNAVAILABLE, - "initial setup not completed", -); - #[derive(Clone)] -pub struct Layer { - app: App, - fallback: F, -} +pub struct Required(pub App); -impl Layer<(StatusCode, &'static str)> { - pub fn or_unavailable(app: App) -> Self { - Self::with_fallback(app, UNAVAILABLE) +impl Required { + pub fn with_fallback(self, fallback: F) -> WithFallback { + let Self(app) = self; + WithFallback { app, fallback } } } -impl Layer { - pub fn with_fallback(app: App, fallback: F) -> Self { - Layer { app, fallback } +impl Layer for Required { + type Service = Middleware; + + fn layer(&self, inner: S) -> Self::Service { + let Self(app) = self.clone(); + Middleware { + inner, + app, + fallback: Unavailable, + } } } -impl tower::Layer for Layer +#[derive(Clone)] +pub struct WithFallback { + app: App, + fallback: F, +} + +impl Layer for WithFallback where Self: Clone, { @@ -86,3 +92,16 @@ where }) } } + +#[derive(Clone)] +pub struct Unavailable; + +impl IntoResponse for Unavailable { + fn into_response(self) -> Response { + ( + StatusCode::SERVICE_UNAVAILABLE, + "initial setup not completed", + ) + .into_response() + } +} -- cgit v1.2.3