use super::Sink;
use crate::{ClassifiedDiagnostic, DiagnosticSeverity, code};
pub type FilterFn<C, S, D = code::DefaultDiscriminant> =
fn(&C, &ClassifiedDiagnostic<S, D>) -> bool;
pub type AddCallback<C, S, D = code::DefaultDiscriminant> = fn(&mut C, &ClassifiedDiagnostic<S, D>);
pub const fn at_least_warning<C, S, D>(
_context: &C,
diagnostic: &ClassifiedDiagnostic<S, D>,
) -> bool {
diagnostic
.severity
.at_least_as_severe_as(&DiagnosticSeverity::Warning)
}
pub const fn at_least_error<C, S, D>(
_context: &C,
diagnostic: &ClassifiedDiagnostic<S, D>,
) -> bool {
diagnostic
.severity
.at_least_as_severe_as(&DiagnosticSeverity::Error)
}
#[derive(Clone, Debug, Hash)]
pub struct Filter<I, C, S, D = code::DefaultDiscriminant> {
inner: I,
pub context: C,
predicate: FilterFn<C, S, D>,
add_callback: AddCallback<C, S, D>,
}
impl<I, C, S, D> Filter<I, C, S, D> {
pub const fn new(sink: I, context: C, filter: FilterFn<C, S, D>) -> Self {
Self {
inner: sink,
context,
predicate: filter,
add_callback: |_, _| {},
}
}
pub const fn set_add_callback(&mut self, callback: AddCallback<C, S, D>) -> &mut Self {
self.add_callback = callback;
self
}
pub const fn with_add_callback(mut self, callback: AddCallback<C, S, D>) -> Self {
self.set_add_callback(callback);
self
}
}
impl<I, C, S, D> Sink<S, D> for Filter<I, C, S, D>
where
I: Sink<S, D>,
{
fn add(&mut self, diagnostic: ClassifiedDiagnostic<S, D>) {
if (self.predicate)(&self.context, &diagnostic) {
(self.add_callback)(&mut self.context, &diagnostic);
self.inner.add(diagnostic);
}
}
}