use std::{cell::Cell, fmt::Display};
pub trait Handler<T> {
fn receive<E: Into<T>>(&self, error: E);
fn has_received(&self) -> bool;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct VoidHandler;
impl<T> Handler<T> for VoidHandler {
fn receive<E: Into<T>>(&self, _error: E) {}
fn has_received(&self) -> bool {
false
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct SilentHandler {
received: Cell<bool>,
}
impl SilentHandler {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl<T> Handler<T> for SilentHandler {
fn receive<E: Into<T>>(&self, _error: E) {
self.received.set(true);
}
fn has_received(&self) -> bool {
self.received.get()
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct PrintHandler {
printed: Cell<bool>,
}
impl PrintHandler {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl<T: Display> Handler<T> for PrintHandler {
fn receive<E: Into<T>>(&self, error: E) {
eprintln!("{}", error.into());
self.printed.set(true);
}
fn has_received(&self) -> bool {
self.printed.get()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_void_handler() {
let handler = VoidHandler;
Handler::<&str>::receive(&handler, "error");
assert!(!Handler::<&str>::has_received(&handler));
}
#[test]
fn test_silent_handler() {
let handler = SilentHandler::new();
Handler::<&str>::receive(&handler, "error");
assert!(Handler::<&str>::has_received(&handler));
}
#[test]
fn test_print_handler() {
let handler = PrintHandler::new();
Handler::<&str>::receive(&handler, "error");
assert!(Handler::<&str>::has_received(&handler));
}
}