#service #context #reference #temp #type

no-std dyn-context

Non-owning service provider pattern implementation

42 releases (17 breaking)

Uses new Rust 2021

new 0.17.1 May 19, 2022
0.16.1 May 17, 2022
0.10.8 Sep 24, 2021
0.7.0 Jul 26, 2021
0.3.2 Sep 21, 2020

#179 in Rust patterns

Download history 17/week @ 2022-01-27 9/week @ 2022-02-03 7/week @ 2022-02-10 36/week @ 2022-02-17 8/week @ 2022-02-24 12/week @ 2022-03-03 68/week @ 2022-03-10 125/week @ 2022-03-17 3/week @ 2022-03-24 8/week @ 2022-03-31 22/week @ 2022-04-07 7/week @ 2022-04-14 4/week @ 2022-04-21 199/week @ 2022-04-28 386/week @ 2022-05-05 968/week @ 2022-05-12

1,564 downloads per month
Used in 4 crates

MIT/Apache

36KB
626 lines

dyn-context

This crate provides simple mechanism for lifetimes and generics safely erasing.

  1. Erasing lifetimes.

    In Rust, lifetimes are intrusive, and sometimes it can lead to an inadequately complex code. Moreover, in some cases it can lead to an impossible code, means code so complex, so it can not make to compile, even it is logically meaningful. (Such situations could occur because Rust does not support existential types with infinite parameters list.)

    The crate provides a way to "compress" several lifetimed references into a one reference to a 'static type. This mechanism guarantees type-safety.

  2. Erasing generics.

    There are many reasons, why generics could be not a best choice in some concrete situation. This library provides State trait, which may be helpful in such cases.

Combining both mechanics (lifetimes compression and dynamic state trait) allows building complex systems with callbacks:

mod call_back {
    use dyn_context::State;

    pub struct CallBack {
        callback: Option<fn(state: &mut dyn State)>
    }

    impl CallBack {
        pub fn new() -> Self { CallBack { callback: None } }

        pub fn set_callback(&mut self, callback: fn(state: &mut dyn State)) {
            self.callback.replace(callback);
        }

        pub fn call_back(&self, state: &mut dyn State) {
            self.callback.map(|callback| callback(state));
        }
    }
}

use call_back::CallBack;
use dyn_context::{SelfState, StateExt, free_lifetimes};

free_lifetimes! {
    struct PrintState {
        value: 'value ref str
    }
}

impl SelfState for PrintState { }

fn main() {
    let mut call_back = CallBack::new();
    call_back.set_callback(|state| {
        let print: &PrintState = state.get();
        println!("{}", print.value());
    });
    PrintStateBuilder {
        value: "Hello, world!"

    }.build_and_then(|state| 
        call_back.call_back(state)
    );
}

Dependencies

~1.3–2MB
~45K SLoC