Expand description
The named_tuple!
macro generates a struct
that manages a set of fields in a tuple
.
The tuple could be access with field getter/setter at runtime.
§Example
named_tuple!(
#[derive(Clone, Copy)]
struct Human<'a> {
name: &'a str,
age: usize,
}
);
named_tuple!(
#[derive(Clone, Copy)]
struct Endpoint(host, port);
);
fn main() {
let human: Human = ("alice", 18).into();
assert_eq!(human.name(), "alice");
assert_eq!(human.age(), 18);
assert_eq!(human.field_values(), ("alice", 18));
let mut endpoint = Endpoint::new("localhost", 80);
assert_eq!(endpoint.host(), "localhost");
assert_eq!(endpoint.port(), 80);
}
§Visibility
The generated struct and its associated fields are not exported out of the current module by default.
A definition can be exported out of the current module by adding pub
before the struct
keyword or the field name:
mod example {
named_tuple!(
#[derive(Clone, Copy)]
pub struct Human<'a> {
pub name: &'a str,
age: usize,
}
);
}
fn main() {
let mut human = example::Human::new("alice", 18);
assert_eq!(human.name(), "alice");
assert_eq!(human.age(), 18); // error: method `age` is private
}
§Attributes
Attributes can be attached to the generated struct by placing them before the struct
keyword.
named_tuple!(
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq)]
struct Human<'a> {
name: &'a str,
age: usize,
}
);
By default, the field getter will return reference of value.
named_tuple!(
struct Endpoint(host, port);
);
fn main() {
let mut endpoint = Endpoint::new("localhost", 80);
assert_eq!(*endpoint.host(), "localhost"); // compare &&str to &str
assert_eq!(*endpoint.port(), 80); // compare &{integer} to {integer}
}
You could add #[derive(Clone, Copy)]
attribute to force it return value.
named_tuple!(
#[derive(Clone, Copy)]
struct Endpoint(host, port);
);
fn main() {
let mut endpoint = Endpoint::new("localhost", 80);
assert_eq!(endpoint.host(), "localhost");
assert_eq!(endpoint.port(), 80);
}
§Trait implementations
The From
, Into
, Deref
, DerefMut
, PartialEq
and PartialOrd
traits are implemented for the struct,
that make the struct could be works with the underline tuple.
named_tuple!(
#[derive(PartialEq, PartialOrd)]
struct Endpoint<'a> {
host: &'a str,
port: u16,
}
);
fn main() {
let endpoint: Endpoint = ("localhost", 80).into(); // From<(...)>
let addr = endpoint.to_socket_addrs().unwrap().collect::<Vec<_>>(); // Deref<Target=(...)>
if endpoint != ("localhost", 443) { // PartialEq<(...)>
if endpoint < ("localhost", 1024) { // PartialOrd<(...)>
let (host, port) = endpoint.into(); // Into<(...)>
}
}
}
Additional traits can be derived by providing an explicit derive
attribute on struct
.
§Serde
For the tuple structs, the serde
support is disabled by default,
you need build named_tuple
with serde
feature in Cargo.toml
[dependencies]
named_tuple = { version = "0.1", features = ["serde"] }
Then the Serialize
and Deserialize
will be implemented when all tuple field type implement it.
named_tuple!(
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Endpoint<'a> {
host: &'a str,
port: u16,
}
);
fn main() {
let endpoint = Endpoint::new("localhost", 80);
let json = serde_json::to_string(&endpoint).unwrap();
assert_eq!(json, "[\"localhost\",80]");
let endpoint2: Endpoint = serde_json::from_str(&json).unwrap();
assert_eq!(endpoint, endpoint2);
}
§Methods
The following methods are defined for the generated struct:
new
: constructs a new named tuple.field_names
: returns a slice of field names.fields
: returns a tuple of field name and value pair.field_values
: return a tuple of field values.
Besides, all the fields have a getter and setter method.
named_tuple!(
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq)]
struct Human<'a> {
name: &'a str,
age: usize,
}
);
fn main() {
let mut human = Human::new("alice", 18);
assert_eq!(human.field_names(), &["name", "age"]);
assert_eq!(human.field_pairs(), (("name", "alice"), ("age", 18)));
assert_eq!(human.field_values(), ("alice", 18));
assert_eq!(human.name(), "alice");
assert_eq!(human.age(), 18);
human.set_name("bob");
human.set_age(20);
assert_eq!(("bob", 20), human.into());
}
§Lifetimes
A named tuple could have multi lifetimes.
pub struct Foo {}
pub enum Bar {}
named_tuple!(
pub struct Test<'a, 'b> {
foo: &'a Foo,
bar: &'b Bar,
}
);
Macros§
- named_
tuple - The macro used to generate tuple with named fields.