Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Mutability

You probably have noticed that both the mutable accessor and setter require the object itself to be mutable. While this is a common requirement in Rust, it is not always possible to fulfill. This is where interior mutability comes into play. FieldX provides support for this pattern via the inner_mut argument, which, combined with the get_mut and set arguments, allows you to mutate a field even when the object itself is not mutable.

use fieldx::fxstruct;

#[fxstruct(get, builder)]
struct Book {
    title:  String,
    author: String,
    year:   u32,
    #[fieldx(get(copy), get_mut, inner_mut)]
    available: u16,
    #[fieldx(set("place_into"), inner_mut)]
    location: String,
}

let book = Book::builder()
    .title("The Hitchhiker's Guide to the Galaxy".to_string())
    .author("Douglas Adams".to_string())
    .year(1979)
    .available(1)
    .location("R12.S2".to_string()) // Row 12, Section 2
    .build()
    .expect("Failed to create book");

*book.available_mut() = 3;
book.place_into("R12.S4".to_string());
assert_eq!(book.available(), 3);
assert_eq!(*book.location(), "R12.S4");

Note

In the above example, while nothing has changed for the available field accessor, which carries the copy sub-argument, the accessor for the location field now requires dereferencing. This is because both field types are now wrapped in a RefCell container which, when borrowed, returns a Ref type. The copy sub-argument simplifies this since returning a value is straightforward. However, the location field accessor still returns a reference, just a different kind of it.

Note

In sync and async modes of operation use of the inner_mut argument is equivalent to using lock.