spacegate_plugin/
layer.rs

1use std::sync::Arc;
2
3use arc_swap::ArcSwap;
4use futures_util::future::BoxFuture;
5use hyper::{Request, Response};
6use spacegate_kernel::{
7    helper_layers::function::{FnLayerMethod, Inner},
8    SgBody,
9};
10
11/// It's a three-layer pointer.
12/// The first layer is an Arc, which makes it reuseable;
13/// The second layer is an ArcSwap, which makes it mutable;
14/// And the third layer is a Box, which allocates the function on the heap.
15#[derive(Clone)]
16pub struct PluginFunction {
17    f: Arc<ArcSwap<InnerBoxPf>>,
18}
19/// A pointer to a heap allocated Plugin Function
20pub(crate) type InnerBoxPf = Box<dyn Fn(Request<SgBody>, Inner) -> BoxFuture<'static, Response<SgBody>> + Send + Sync + 'static>;
21impl PluginFunction {
22    pub fn new(f: InnerBoxPf) -> Self {
23        Self {
24            f: Arc::new(ArcSwap::from_pointee(f)),
25        }
26    }
27}
28
29impl PluginFunction {
30    pub fn swap(&self, f: Box<dyn Fn(Request<SgBody>, Inner) -> BoxFuture<'static, Response<SgBody>> + Send + Sync + 'static>) {
31        self.f.store(f.into());
32    }
33}
34
35impl FnLayerMethod for PluginFunction {
36    async fn call(&self, req: Request<SgBody>, inner: Inner) -> Response<SgBody> {
37        let f = self.f.load();
38        f(req, inner).await
39    }
40}