New to rust, how to handle default fields?


#1

I’m new to Rust and would like to know what is currently idiomatic way of handling default “changes” field in Aggregate trait in code snippet below:

#[allow(non_camel_case_types)]
enum Event {
  COUNTER_DECREASE { amount: i32, },
  COUNTER_INCREASE { amount: i32, },
}

trait Aggregate {
  changes: Vec<Event>;

  fn apply(&mut self, e: Event);
  fn raise(&mut self, e: Event) {
    self.apply(e);
    self.changes.push(e);
  }
}

struct Counter {
  count: i32,
}

impl Counter {
  fn decrease(&mut self, amount: i32) {
    self.raise(Event::COUNTER_DECREASE { amount: amount });
  }

  fn increase(&mut self, amount: i32) {
    self.raise(Event::COUNTER_INCREASE { amount: amount });
  }
}

impl Aggregate for Counter {
  fn apply(&mut self, e: Event) {
    match e {
      Event::COUNTER_DECREASE { amount, .. } => self.count = self.count - amount,
      Event::COUNTER_INCREASE { amount, .. } => self.count = self.count + amount,
    }
  }
}

`


#2

Traits cannot store data, so this code doesn’t actually work.

For default values, http://doc.rust-lang.org/std/default/trait.Default.html is the way to go.

#[derive(Default,Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    // both of these lines work
    let p: Point = Default::default();
    let p = <Point as Default>::default();

    println!("{:?}", p);
}

#3

Exactly, code doesn’t compile because of “changes” field in trait. I want “changes” field to be accessible for structs implementing Aggregate trait. Sorry, but I don’t get how #[derive(Default)] could achieve that.


#4

The traits cannot carry data, they’re really just behavioral. A common solution to your example would be to have the Aggregate trait expect the type to define a fn changes(&mut self) -> &mut Vec<Event>;, or fn add_change(&mut self, e: Event); if you want to be storage-agnostic.


#5

There is an RFC that would allow this, but for now you will need to include a changes field in the struct and add a .changes() method to the trait to access it.


#6

Thanks for your replies, much appreciated.


#7

In the end I’ve settled with macro implemented for default “changes” field. Playground code snippet - http://is.gd/bt1jt1 for anyone interested or willing to comment on implementation.