use crate::logging::format::{LogFormat, ReportLog};
use futures_sink::Sink;
use pin_project::pin_project;
use std::pin::Pin;
use std::task::{Context, Poll};
use witchcraft_metrics::MetricRegistry;
#[pin_project]
pub struct MetricsAppender<S, T>
where
T: LogFormat,
{
#[pin]
inner: S,
reporter: T::Reporter,
}
impl<S, T> MetricsAppender<S, T>
where
T: LogFormat,
{
pub fn new(inner: S, metrics: &MetricRegistry) -> Self {
MetricsAppender {
inner,
reporter: <T::Reporter as ReportLog<T>>::new(metrics),
}
}
}
impl<S, T> Sink<T> for MetricsAppender<S, T>
where
S: Sink<T>,
T: LogFormat,
{
type Error = S::Error;
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_ready(cx)
}
fn start_send(self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> {
let this = self.project();
this.reporter.report(&item);
this.inner.start_send(item)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_close(cx)
}
}