Skip to content

Instantly share code, notes, and snippets.

@abrodersen
Last active October 17, 2017 19:43
Show Gist options
  • Save abrodersen/00f80b491400671a8d707100ce5daee0 to your computer and use it in GitHub Desktop.
Save abrodersen/00f80b491400671a8d707100ce5daee0 to your computer and use it in GitHub Desktop.
Rust Plugin Example
// I want to create a simple plugin framework for a library I'm writing
// One of the plugins I want to write makes use of a dependency that is very
// restrictive: it enforces the use of references rather than owned values.
trait Modify {
fn add_one(&mut self);
}
trait Plugin<'a, T>
where T: Modify
{
fn get(&'a mut self) -> T;
}
// This is an external dependency and cannot be changed
type AnnoyingDependency<'a> = &'a mut u8;
struct TestPlugin<'a> {
// this reference is required
value: AnnoyingDependency<'a>,
}
struct TestModify<'a> {
test: &'a mut TestPlugin<'a>,
}
impl<'a> Plugin<'a, TestModify<'a>> for &'a mut TestPlugin<'a> {
fn get(&'a mut self) -> TestModify<'a> {
TestModify { test: self }
}
}
impl<'a> Modify for TestModify<'a> {
fn add_one(&mut self) {
// Need mutable access to underlying dependency reference here
*self.test.value += 1;
}
}
fn main() {
let mut original = 1;
{
let mut test = TestPlugin { value: &mut original };
process(&mut test);
}
println!("new value: {}", original);
}
fn process<'a, P, M>(plugin: P)
where P: Plugin<'a, M> + 'a, M: Modify
{
// want to call generic code here
let mut inner = plugin.get();
inner.add_one();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment