spacegate-kernel 0.2.0-alpha.4

A library-first, lightweight, high-performance, cloud-native supported API gateway
Documentation
use hyper::service::Service;
use tower_layer::Layer;

use crate::{injector::Inject, SgRequest};
#[derive(Debug, Clone)]
pub struct InjectorLayer<I> {
    inject: I,
}

#[derive(Debug, Clone)]
pub struct Injector<I, S> {
    inject: I,
    inner: S,
}

impl<I> InjectorLayer<I> {
    pub fn new(inject: I) -> Self {
        Self { inject }
    }
}

impl<I, S> Injector<I, S> {
    pub fn new(inject: I, inner: S) -> Self {
        Self { inject, inner }
    }
}

impl<S, I> Layer<S> for InjectorLayer<I>
where
    I: Clone,
{
    type Service = Injector<I, S>;

    fn layer(&self, inner: S) -> Self::Service {
        Injector::new(self.inject.clone(), inner)
    }
}

impl<I, S> Service<SgRequest> for Injector<I, S>
where
    I: Inject,
    S: Service<SgRequest>,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = S::Future;

    fn call(&self, mut req: SgRequest) -> Self::Future {
        if let Err(e) = self.inject.inject(&mut req) {
            tracing::error!("inject error: {}", e);
        }
        self.inner.call(req)
    }
}