scoped-callback

Crates.ioscoped-callback
lib.rsscoped-callback
version0.2.0
sourcesrc
created_at2019-12-25 10:50:12.388705
updated_at2020-02-09 17:11:21.393973
descriptionRegister scoped functions with local references to 'static lifetime callbacks in a safe manner
homepagehttps://github.com/gardell/scoped-callback
repositoryhttps://github.com/gardell/scoped-callback
max_upload_size
id192311
size33,646
Johan Gardell (gardell)

documentation

https://docs.rs/scoped-callback

README

Docs

scoped-callback

Allows registering scoped functions with local borrows with code that expect functions taking 'static lifetimes.

Motivating example:

/// 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 and scope_async_local as well for versions that work with async scopes.

How is this safe?

There are three important concepts in this implementation:

  • register returns a Registered instance, which when Drop-ed causes the callback to be de-registered using the provided function.
  • In case the Registered instance is not 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.
  • In case the given de-register function doesn't actually de-register the callback, and for some reason the callback given to the register function is called after the closure passed to scope, the call will cause a panic!.

no_std

This crate supports no_std by disabling its std feature.

License: Apache-2.0

Commit count: 36

cargo fmt