use cot::middleware::{IntoCotErrorLayer, IntoCotResponseLayer};
use cot::project::MiddlewareContext;
#[cfg(feature = "live-reload")]
type LiveReloadLayerType = tower::util::Either<
(
IntoCotErrorLayer,
IntoCotResponseLayer,
tower_livereload::LiveReloadLayer,
),
tower::layer::util::Identity,
>;
#[cfg(feature = "live-reload")]
#[derive(Debug, Clone)]
pub struct LiveReloadMiddleware(LiveReloadLayerType);
#[cfg(feature = "live-reload")]
impl LiveReloadMiddleware {
#[must_use]
pub fn new() -> Self {
Self::with_enabled(true)
}
#[must_use]
pub fn from_context(context: &MiddlewareContext) -> Self {
Self::with_enabled(context.config().middlewares.live_reload.enabled)
}
fn with_enabled(enabled: bool) -> Self {
let option_layer = enabled.then(|| {
(
IntoCotErrorLayer::new(),
IntoCotResponseLayer::new(),
tower_livereload::LiveReloadLayer::new(),
)
});
Self(tower::util::option_layer(option_layer))
}
}
#[cfg(feature = "live-reload")]
impl Default for LiveReloadMiddleware {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "live-reload")]
impl<S> tower::Layer<S> for LiveReloadMiddleware {
type Service = <LiveReloadLayerType as tower::Layer<S>>::Service;
fn layer(&self, inner: S) -> Self::Service {
self.0.layer(inner)
}
}
#[cfg(test)]
mod tests {
use crate::config::{LiveReloadMiddlewareConfig, MiddlewareConfig, ProjectConfig};
use crate::{Bootstrapper, Project};
#[cot::test]
async fn live_reload_from_context_enabled() {
test_live_reload_from_context(true).await;
}
#[cot::test]
async fn live_reload_from_context_disabled() {
test_live_reload_from_context(false).await;
}
async fn test_live_reload_from_context(enabled: bool) {
struct TestProject;
impl Project for TestProject {}
let middleware_config = LiveReloadMiddlewareConfig::builder()
.enabled(enabled)
.build();
let config = ProjectConfig::builder()
.middlewares(
MiddlewareConfig::builder()
.live_reload(middleware_config)
.build(),
)
.build();
let bootstrapper = Bootstrapper::new(TestProject)
.with_config(config)
.with_apps()
.with_database()
.await
.unwrap()
.with_cache()
.await
.unwrap();
let middleware = super::LiveReloadMiddleware::from_context(bootstrapper.context());
match middleware.0 {
tower::util::Either::Left(_) => {
assert!(enabled, "LiveReloadLayer should be disabled");
}
tower::util::Either::Right(_) => {
assert!(!enabled, "LiveReloadLayer should be enabled");
}
}
}
}