summaryrefslogtreecommitdiff
path: root/src/setup
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-06-17 01:22:54 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-06-17 01:22:54 -0400
commit43375bcb875a31ce8c6132ce78552d45f64b261b (patch)
tree6ea93d417f329baccaa84f1d557638f54f3f2d37 /src/setup
parent424fb08ecd315c67dd3862c29e87eea7bf32f65c (diff)
Use a fluent style for the middleware layers.
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.
Diffstat (limited to 'src/setup')
-rw-r--r--src/setup/mod.rs2
-rw-r--r--src/setup/required.rs53
2 files changed, 37 insertions, 18 deletions
diff --git a/src/setup/mod.rs b/src/setup/mod.rs
index 62972b3..a4b821c 100644
--- a/src/setup/mod.rs
+++ b/src/setup/mod.rs
@@ -3,4 +3,4 @@ pub mod repo;
mod required;
mod routes;
-pub use self::{required::Layer as Required, routes::router};
+pub use self::{required::Required, routes::router};
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<F> {
- 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<F>(self, fallback: F) -> WithFallback<F> {
+ let Self(app) = self;
+ WithFallback { app, fallback }
}
}
-impl<F> Layer<F> {
- pub fn with_fallback(app: App, fallback: F) -> Self {
- Layer { app, fallback }
+impl<S> Layer<S> for Required {
+ type Service = Middleware<S, Unavailable>;
+
+ fn layer(&self, inner: S) -> Self::Service {
+ let Self(app) = self.clone();
+ Middleware {
+ inner,
+ app,
+ fallback: Unavailable,
+ }
}
}
-impl<S, F> tower::Layer<S> for Layer<F>
+#[derive(Clone)]
+pub struct WithFallback<F> {
+ app: App,
+ fallback: F,
+}
+
+impl<S, F> Layer<S> for WithFallback<F>
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()
+ }
+}