This seems like a use case for properties, how else would you solve it in Rust?


#1

A while back I had a project to write a Game Boy Advance emulator. One thing I ran into which I had no good solution to was how to ergonomically model the register banks on the ARM7TDMI.

In other languages, I’d use properties, something like this Rust-ish pseudocode.

struct Processor {
    mode: ProcessorMode,
    r0: u32,
    // ...
    r8_sys: u32,
    r8_fiq: u32,
    r9_sys: u32,
    r9_fiq: u32,
    // ...

    property r8: u32 {
        get(&self) -> u32 {
            match self.mode {
                ProcessorMode::Fiq => self.r8_fiq,
                _ => self.r8_sys,
            }
        },
        set(&mut self, arg: u32) {
            match self.mode {
                ProcessorMode::Fiq => self.r8_fiq = arg,
                _ => self.r8_sys = arg,
            };
        },
    },
    // ...
}

When I asked on IRC I was pointed in the direction of a trick using Deref to redirect access to a substructure, but I’ve since learned that’s considered an anti-pattern. As such I am left wondering: is there a better way to do this in Rust?


#2

Rust doesn’t have a syntax sugar for getters/setters. I wouldn’t be surprised if that was a deliberate design choice (in order to make direct access explicit from the syntax).

Unfortunately getter/setter methods borrow entire self, which can get in the way if you need to mutably borrow more than one field at a time.

In your case I see potential simplification:

struct Registers { r8, r9 }

struct Processor {
  sys: Registers,
  fiq: Registers,
}

which would let you have one getter/setter for all registers.

Alternatively if switching modes doesn’t keep the values, then enum Registers { Fiq { r8, r9 }, Sys { r8, r9 }} would be more idiomatic than separate C-like enum and data.