//! Example of using supply to access a value as different trait objects. use supply::lt_structure; use supply::prelude::*; use supply::tag::{Mut, Ref, Tag}; struct Demo { value: u8, } impl A for Demo { fn do_a(&self) -> u8 { self.value } } impl B for Demo { fn do_b(&mut self, value: u8) { self.value = value; } } impl<'r> Provider<'r> for Demo { type Lifetimes = l!['r]; fn provide(&'r self, want: &mut dyn Want) { want.provide_tag::>(self); } fn provide_mut(&'r mut self, want: &mut dyn Want) { // This doesn't work because self would be borrowed twice. // This is fine for provide above. // // want.provide_tag::<&DynA>(self) // .provide_tag::<&mut DynB>(self); // This way works because the borrow checker knows that if self is used then // nothing after this can be run (because provide_with returns None). let Some(this) = want.provide_with::, _, _>(self, |this| this) else { return; }; // The last one can be normal. want.provide_tag::>(this); } } #[test] fn example() { let mut demo = Demo { value: 0 }; // Erase the type so the following doesn't know it's a Demo. let p: &mut dyn for<'r> ProviderDyn<'r> = &mut demo; // Access demo as a &dyn A to call do_a. assert_eq!(p.request::>().unwrap().do_a(), 0); // Access demo as a &mut dyn B to call do_b. p.request_mut::>().unwrap().do_b(5); // Access demo as a &dyn A to call do_a again. assert_eq!(p.request::>().unwrap().do_a(), 5); } trait A { fn do_a(&self) -> u8; } enum DynA {} impl<'u> WithLt for DynA { type Reified = dyn A + 'u; } impl Tagged for DynA { type Tag = Self; } impl Tag for DynA { type LifetimesTag = lt_structure!['_]; } trait B { fn do_b(&mut self, value: u8); } enum DynB {} impl<'u> WithLt for DynB { type Reified = dyn B + 'u; } impl Tagged for DynB { type Tag = Self; } impl Tag for DynB { type LifetimesTag = lt_structure!['_]; }