use tower::layer::util::Stack;
use crate::plugin::{PluginPipeline, PluginStack};
use crate::{
operation::{Operation, OperationShape},
plugin::Plugin,
};
use super::{layer::InstrumentLayer, sensitivity::Sensitivity};
#[derive(Debug)]
pub struct InstrumentPlugin;
impl<P, Op, S, L> Plugin<P, Op, S, L> for InstrumentPlugin
where
Op: OperationShape,
Op: Sensitivity,
{
type Service = S;
type Layer = Stack<L, InstrumentLayer<Op::RequestFmt, Op::ResponseFmt>>;
fn map(&self, operation: Operation<S, L>) -> Operation<Self::Service, Self::Layer> {
let layer = InstrumentLayer::new(Op::NAME)
.request_fmt(Op::request_fmt())
.response_fmt(Op::response_fmt());
operation.layer(layer)
}
}
pub trait InstrumentExt<CurrentPlugins> {
fn instrument(self) -> PluginPipeline<PluginStack<InstrumentPlugin, CurrentPlugins>>;
}
impl<CurrentPlugins> InstrumentExt<CurrentPlugins> for PluginPipeline<CurrentPlugins> {
fn instrument(self) -> PluginPipeline<PluginStack<InstrumentPlugin, CurrentPlugins>> {
self.push(InstrumentPlugin)
}
}