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())),
)
}
}