What is an idiomatic way to have multiple structs with the same properties in Rust?

Viewed 2373

I'm aware that Rust does not have inheritance and that the language provides and easy way to share different implementations of the same methods across objects through the use of Traits. But is there an idiomatic way to share property name definitions or do they need to be defined on each struct?

My use case is that I have many different structs that track some information. Each piece of information can be updated and I want each struct to know the date of its last update. Is there a common pattern (maybe macros?) to add a last_update property to all the structs or must I add it to each struct explicitly?

1 Answers

There is currently no way to do this via traits, the closest thing is the "Fields in Traits" RFC (discussion, RFC), but that doesn't seem terribly active as of now.

The simplest way to do this is to have a type / struct with a method and include that field in any struct you want:

struct UpdateTimestamp {
    timestamp: Timestamp, // dummy type
}

impl UpdateTimestamp {
    fn update(&mut self) {
        self.timestamp = now(); // dummy function
    }
    fn last_updated(&self) -> Timestamp {
        self.timestamp
    }
}

You could then include this in any struct where you want the functionality:

struct MyStruct {
    my_field: u32,
    my_other_field: i32,
    update_ts: UpdateTimestamp,
}

impl MyStruct {
    fn my_field(&self) -> u32 {
        // Getter - no update
        self.my_field
    }
    fn set_my_field(&mut self, my_field: u32) {
        self.update_ts.update();
        self.my_field = my_field;
    }
    fn last_updated(&self) -> Timestamp {
        self.update_ts.last_updated()
    }
}

Now you could write a complicated macro for this which automates the implementation part (injects updates into the setters and the last_updated method in the impl block), but unless you're doing this a lot I don't think it would be worth it.

Related