Skip to content
Type-Safe, Lazily Evaluated, Plugins for Extensible Types
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples
src
.gitignore
.travis.yml
Cargo.toml
README.md

README.md

Plugin

Type-Safe, Lazily Evaluated, Plugins for Extensible Types

Plugins provide a consistent interface for mixin methods. You can use a plugin anywhere you would use a "mixin" trait and an implementation.

Example Usage

// Define a struct.
struct IntPlugin;

// Map it onto an `i32` value.
impl typemap::Key for IntPlugin { type Value = i32; }

// Define the plugin evaluation function.
// `Extended` is a type that implements `Extensible`.
impl Plugin<Extended> for IntPlugin {
    type Error = ();

    fn eval(_: &mut Extended) -> Result<i32, ()> {
        Ok(0i32)
    }
}
assert_eq!(extended.get::<IntPlugin>().unwrap(), 0i32);

To do the same thing with a trait, one could do:

trait IntProducer {
    fn get_int_value(&self) -> Option<i32>;
}

impl IntProducer for Extended {
    fn get_int_value(&self) -> Option<i32> {
        Some(0i32)
    }
}

Although using a raw trait is less code, plugins provide the following advantages:

  • Automatic caching of values. Calling a method again is a constant time operation! This is particularly useful in pipeline structures where only the extensible object is passed around.
  • A consistent interface, which also allows for neater name clash resolution. Two modules that provide PluginX can be differentiated using a module prefix.
e.get::<mod1::PluginX>();
e.get::<mod2::PluginX>();
You can’t perform that action at this time.