![](https://github.com/gardell/scoped-callback/workflows/CI/badge.svg) [![Docs](https://docs.rs/scoped-callback/badge.svg)](https://docs.rs/scoped-callback/latest/scoped_callback) # scoped-callback Allows registering scoped functions with local borrows with code that expect functions taking `'static` lifetimes. Motivating example: ```rust /// Function for registering a callback with a `'static` lifetime. fn register(callback: Box<dyn FnMut(i32)>) -> Box<dyn FnMut(i32)> { callback } /// Function for de-registering the handle returned by `register`, /// in this case the callback itself. fn deregister(_callback: Box<dyn FnMut(i32)>) {} /// Variable that can be borrowed from inside the callback closure let a = 42; /// After returning from the closure, `scope` guarantees that any callbacks /// that have not yet been de-registered are de-registered. scope(|scope| { /// Register the given closure, which can borrow from the stack outside `scope` /// using the `register` and `deregister` functions declared above. /// The returned handle will cause a de-register when dropped. let _registered = scope.register( |_| { let b = a * a; println!("{}", b); }, register, deregister, ); }); ``` See [scope_async](https://docs.rs/scoped-callback/latest/fn.scope_async.html) and [scope_async_local](fn.scope_async_local.html) as well for versions that work with `async` scopes. ## How is this safe? There are three important concepts in this implementation: * [register](https://docs.rs/scoped-callback/latest/struct.Scope.html#method.register) returns a [Registered](struct.Registered.html) instance, which when [Drop](https://docs.rs/scoped-callback/latest/struct.Registered.html#impl-Drop)-ed causes the callback to be de-registered using the provided function. * In case the [Registered](https://docs.rs/scoped-callback/latest/struct.Registered.html) instance is not [Drop](https://docs.rs/scoped-callback/latest/struct.Registered.html#impl-Drop)-ed, for example by calling `std::mem::forget` (which is *not* `unsafe`!) the de-registering using the provided function will instead happen after leaving the closure passed to [scope](https://docs.rs/scoped-callback/latest/fn.scope.html). * In case the given de-register function doesn't actually de-register the callback, and for some reason the callback given to the [register](https://docs.rs/scoped-callback/latest/struct.Scope.html#method.register) function is called after the closure passed to [scope](https://docs.rs/scoped-callback/latest/fn.scope.html), the call will cause a `panic!`. ## `no_std` This crate supports `no_std` by disabling its `std` feature. License: Apache-2.0