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

Accessors

In FieldX, there are two ways to get an accessor method for a field:

  • Explicitly, by using the get argument.
  • Implicitly, when the use of another argument makes no sense without an accessor.

There are also two kinds of accessors: immutable and mutable. The latter is never generated implicitly and is only available with the use of the get_mut argument.

By default, an accessor returns a reference to the field value[^unless_other_args]:

use fieldx::fxstruct;

#[fxstruct(get, builder)]
struct Book {
    title:  String,
    author: String,
    year:   u32,
}

let book = Book::builder()
    .title("The Hitchhiker's Guide to the Galaxy".to_string())
    .author("Douglas Adams".to_string())
    .year(1979)
    .build()
    .expect("Failed to create book");

let title: &str = book.title();
let author: &str = book.author();
let year: &u32 = book.year();
assert_eq!(title, "The Hitchhiker's Guide to the Galaxy");
assert_eq!(author, "Douglas Adams");
assert_eq!(year, &1979);

So far, so good! But, wait, year? This is disgusting!

use fieldx::fxstruct;

#[fxstruct(get, builder)]
struct Book {
    title:  String,
    #[fieldx(get(clone))]
    author: String,
    #[fieldx(get(copy))]
    year:   u32,
}

let book = Book::builder()
    .title("The Hitchhiker's Guide to the Galaxy".to_string())
    .author("Douglas Adams".to_string())
    .year(1979)
    .build()
    .expect("Failed to create book");

let title: &str = book.title();
let author: String = book.author();
let year: u32 = book.year();
assert_eq!(title, "The Hitchhiker's Guide to the Galaxy");
assert_eq!(author, "Douglas Adams".to_string());
assert_eq!(year, 1979);

Now, this is much better! The get(copy) can be used with types that implement the Copy trait, such as usize, u32, etc., to get the value itself rather than a reference to it.

Along the lines, we use this sample to showcase two more things:

  • The get(clone) can be used with types that implement the Clone trait, such as String, to get a cloned value.
  • It is possible to override a struct-level default argument for a specific field, like we did with get(copy) for the year field and get(clone) for the author field.

And finally, let's have a quick look at the mutable accessors:

use fieldx::fxstruct;

#[fxstruct(get, builder)]
struct Book {
    title:  String,
    author: String,
    #[fieldx(get(copy))]
    year:   u32,
    #[fieldx(get(copy), get_mut, builder(off), default(false))]
    borrowed: bool,
}

let mut book = Book::builder()
    .title("The Hitchhiker's Guide to the Galaxy".to_string())
    .author("Douglas Adams".to_string())
    .year(1979)
    .build()
    .expect("Failed to create book");

assert!(!book.borrowed());
*book.borrowed_mut() = true;
assert!(book.borrowed());

Note

As helper attributes, get and get_mut can take a literal value sub-argument that would give a name to the accessor method when used at the field level, or define a custom method name prefix for default accessor names when used at the struct level.

use fieldx::fxstruct;

#[fxstruct(get("get_"), builder)]
struct Book {
    title:  String,
    author: String,
    #[fieldx(get("published", copy))]
    year:   u32,
}

let book = Book::builder()
    .title("The Hitchhiker's Guide to the Galaxy".to_string())
    .author("Douglas Adams".to_string())
    .year(1979)
    .build()
    .expect("Failed to create book");

assert_eq!(book.get_title(), "The Hitchhiker's Guide to the Galaxy");
assert_eq!(book.get_author(), "Douglas Adams");
assert_eq!(book.published(), 1979);