supply 0.3.1

Provider API for arbitrary number of lifetimes.
Documentation
//! Example of using supply to access a value as different trait objects.

use supply::prelude::*;
use ty_tag::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<Self::Lifetimes>) {
        want.provide_tag::<&dyn A>(self);
    }

    fn provide_mut(&'r mut self, want: &mut dyn Want<Self::Lifetimes>) {
        // 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::<&dyn A, _, _>(self, |this| this) else {
            return;
        };

        // The last one can be normal.
        want.provide_tag::<&mut dyn B>(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::<&dyn A>().unwrap().do_a(), 0);

    // Access demo as a &mut dyn B to call do_b.
    p.request_mut::<&mut dyn B>().unwrap().do_b(5);

    // Access demo as a &dyn A to call do_a again.
    assert_eq!(p.request::<&dyn A>().unwrap().do_a(), 5);
}

trait A {
    fn do_a(&self) -> u8;
}

#[tag]
type DynA<'u> = dyn A + 'u;

trait B {
    fn do_b(&mut self, value: u8);
}

#[tag]
type DynB<'u> = dyn B + 'u;