I'm pretty new to Rust and I've been slowly following an arcade game tutorial which has been a great help with the concepts it goes through.

In part nine of the tutorial, in which the main menu is created, the author suggests 'homework' for the reader of making the labels on the main menu ("New Game", "Quit") animate their change in size when focused and unfocused, rather than jump to their idle/focused size. This is where I have been having difficulty...

The basic layout of the relevant parts of the code before I started to implement the change is the following:

// equivalent to 'menu option' struct Action { /// function executed if action chosen func: Box<Fn(&mut Phi) -> ViewAction>, label: &'static str, idle_sprite: Sprite, // smaller (32) focus_sprite: Sprite, // larger (38) // ... } impl Action { fn new(phi: &mut Phi, label: &'static str, func: Box<Fn(&mut Phi) -> ViewAction>) -> Action { // ... } struct MainMenuView { actions: Vec<Action>, selected: i8, // ... } impl MainMenuView { pub fn new(phi: &mut Phi) -> MainMenuView { // ... } } impl View for MainMenuView { fn render(&mut self, phi: &mut Phi, elapsed: f64) -> ViewAction { // ... for (i, action) in self.actions.iter().enumerate() { // ... } } } fn main() { ::phi::spawn("Arcade Shooter", |phi| { Box::new(::views::main_menu::MainMenuView::new(phi)) }); }

My first thought for the animation was to make it dynamically create a sprite based on an interpolated size between idle_size and focus_size using time elapsed since focus change using methods on Action to focus and defocus to change a current_size field that would be used to generate a sprite for a sprite field.

This required a mutable binding of the Action struct, which took me a little while to work out as there was no let binding anywhere, but seemed to be just about possible by changing the constructor: Action::new(...) -> &mut action , and lots of explicitly marking lifetimes (which had its own issues, but this is getting too long as it is). I then realised that the MainMenuView would have to be mutably bound as well, at which point I stopped this path (I hadn't managed to successfully compile since starting it), as this seemed a really inelegant solution that made basically everything mutable, surely defeating the point of rust's immutability default...

I then wondered whether I could just create a new MainMenuView with a new Action with the new sprite , which could probably work (changing view to another MainMenuView ), but this seems like a really wasteful way to just change the size of some text and again is pretty inelegant.

After that, I remembered Cell , but when trying this to make the actions for MainMenuView a Vec<Cell<Actions>> , I found Cell only works with Copy types. This might have been ok (I don't have enough experience to know), but the func field of Action does not implement Copy (and I'm not sure if it can?) and so Action cannot #[derive(Copy)] . Dead end without restructuring a large section of the program to not have func in Action ?

This is the end of my main question - basically, what do you do when you have structs nested and you want to have a deep field mutate, but can't put a Cell around it (afaik)? And is this a structural issue with the code such that I should be avoiding this issue in the first place?