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 theClone
trait, such asString
, 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 theyear
field andget(clone)
for theauthor
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());
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);