[][src]Crate named_tuple

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.