Skip to content

Instantly share code, notes, and snippets.

@tuzz
Created August 6, 2018 19:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuzz/e3728a407c42f993fc39271427b7c350 to your computer and use it in GitHub Desktop.
Save tuzz/e3728a407c42f993fc39271427b7c350 to your computer and use it in GitHub Desktop.
A Rust proof-of-concept from the August 2018 Rust meeting in London.
/* This is a proof-of-concept, inspired by clojure, that stores just the
* transitions between multiple Foo structs, rather than copying the entire
* struct's fields each time.
*/
#[derive(Default)] // <-- this derives Foo::default() which creates a Foo struct
// with a and b initialized to zero.
struct Foo {
a: u8,
b: u8,
}
struct ActionHolder {
actions: Vec<Action>, // <-- this struct holds a vector of 'actions'
}
impl ActionHolder {
fn apply(&self, foo: &mut Foo) {
for action in self.actions.iter() { // iterate through all actions
foo.apply(action); // and apply them
}
}
fn inverse_apply(&self, foo: &mut Foo) {
for action in self.actions.iter().rev() { // do the same, but in reverse
foo.apply(action);
}
}
}
impl Foo {
fn foo(&mut self, a: u8) {
self.a = a;
}
fn bar(&mut self, b: u8) {
self.b = b;
}
fn apply(&mut self, action: &Action) {
match action {
&Action::Foo(value) => self.foo(value),
&Action::Bar(value) => self.bar(value),
}
}
}
enum Action {
Foo(u8),
Bar(u8),
}
fn main() {
let mut f = Foo::default();
let holder = ActionHolder {
actions: vec![Action::Foo(123), Action::Foo(10), Action::Bar(50)],
};
holder.apply(&mut f);
assert_eq!(f.a, 10);
holder.inverse_apply(&mut f);
assert_eq!(f.a, 123);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment