use contextual::{DisplayWithContext, WithContext};
pub trait Handler<N, W> {
fn handle(&mut self, vocabulary: &N, warning: W);
}
impl<N, W> Handler<N, W> for () {
fn handle(&mut self, _vocabulary: &N, _warning: W) {}
}
impl<N, W, H: Handler<N, W>> Handler<N, W> for &mut H {
fn handle(&mut self, vocabulary: &N, warning: W) {
H::handle(*self, vocabulary, warning);
}
}
pub struct Print;
impl<N, W: std::fmt::Display> Handler<N, W> for Print {
fn handle(&mut self, _vocabulary: &N, warning: W) {
eprintln!("{warning}");
}
}
pub struct PrintWith;
impl<N, W: DisplayWithContext<N>> Handler<N, W> for PrintWith {
fn handle(&mut self, vocabulary: &N, warning: W) {
eprintln!("{}", warning.with(vocabulary));
}
}
pub struct WarningBuf<W>(pub Vec<W>);
impl<W> Default for WarningBuf<W> {
fn default() -> Self {
Self(Vec::new())
}
}
impl<W> WarningBuf<W> {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl<N, W> Handler<N, W> for WarningBuf<W> {
fn handle(&mut self, _vocabulary: &N, warning: W) {
self.0.push(warning);
}
}