use std::fmt::{Debug, Display};
use supply::prelude::*;
use supply::provide::ProvideTag;
trait Error: Debug + for<'r> ProviderDyn<'r> {}
impl<T: Debug + for<'r> ProviderDyn<'r>> Error for T {}
#[derive(Debug)]
struct MyError {
count: i32,
}
impl Display for MyError {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
todo!()
}
}
impl<'r> Provider<'r> for MyError {
type Lifetimes = l!['r];
fn provide(&'r self, want: &mut dyn Want<Self::Lifetimes>) {
want.provide_value(self.count);
}
fn provide_mut(&'r mut self, want: &mut dyn Want<Self::Lifetimes>) {
want.provide_value(&mut self.count);
}
}
fn log<E: ?Sized + Error>(e: &mut E) -> String {
if let Some(count) = e.request_mut::<&mut i32>() {
*count += 1;
}
if let Some(count) = e.request::<i32>() {
return format!("count: {count}");
}
format!("{e:?}")
}
#[test]
fn custom_error() {
let mut my = MyError { count: 42 };
let e: &mut dyn Error = &mut my;
assert_eq!(log(e), "count: 43");
assert_eq!(log(e), "count: 44");
let mut x = 123;
let e: &mut dyn Error = ProvideTag::<_, i32>::from_mut(&mut x);
assert_eq!(log(e), "ProvideTag(124)");
assert_eq!(log(e), "ProvideTag(125)");
}
struct Error2 {
a: i32,
b: i32,
}
impl<'r> Provider<'r> for Error2 {
type Lifetimes = l![];
fn provide(&'r self, want: &mut dyn Want<Self::Lifetimes>) {
if let Some(want) = want.try_for::<i32>() {
want.fulfill(self.a + self.b);
}
}
}
#[test]
fn error_2() {
let e = Error2 { a: 1, b: 4 };
assert_eq!(e.request::<i32>().unwrap(), 5);
assert!(e.request::<bool>().is_none());
}