dipper 0.5.3

An out-of-the-box modular dependency injection web application framework.
Documentation
use std::sync::Arc;

use ::salvo::prelude::*;

use super::Manifest;

pub(super) struct Routable {
    manifest: Arc<Manifest>,
    unroutable_scribe: Arc<dyn UnroutableScribe>,
}

impl Routable {
    pub(crate) fn new(manifest: Arc<Manifest>, unroutable_scribe: Option<Arc<dyn UnroutableScribe>>) -> Self {
        Self {
            manifest,
            unroutable_scribe: unroutable_scribe.unwrap_or(Arc::new(DefaultUnroutableScribe)),
        }
    }
}

#[async_trait]
impl Handler for Routable {
    async fn handle(&self, _req: &mut Request, depot: &mut Depot, res: &mut Response, ctrl: &mut FlowCtrl) {
        if !*self.manifest.routable().read().await {
            self.unroutable_scribe.reject_render(&self.manifest, res);
            ctrl.skip_rest();
        } else {
            depot.inject(self.manifest.clone());
        }
    }
}

pub trait UnroutableScribe: Send + Sync + 'static {
    fn reject_render(&self, manifest: &Manifest, res: &mut Response);
}

#[non_exhaustive]
pub struct DefaultUnroutableScribe;
impl UnroutableScribe for DefaultUnroutableScribe {
    fn reject_render(&self, manifest: &Manifest, res: &mut Response) {
        res.stuff(
            StatusCode::PAYMENT_REQUIRED,
            Text::Plain(format!("The {} module is not enabled!", manifest.name())),
        )
    }
}