Skip to main content

Crate name_index

Crate name_index 

Source
Expand description

Dynamic struct field indexing library

name-index implements functionality to allow users to dynamically access the fields of realitively-homogenous structs by name at runtime.

This functionality may prove useful for problems where fixed key-value pairs are mapped as fields of a struct (for example to aid performance and allow compile-time type checking) but which need to be accessed sparingly at runtime by their respective name.

The lookup functionality is not optimized for performance. In cases where this lookup is frequently used, it is likely better to use alternatives like std::collections::HashMap.

§Example

use name_index::NameIndex;

#[derive(Default, NameIndex)]
struct MyStruct {
    // The #[index] attributes tells the derive macro to
    // start indexing all u32 fields from here on
    #[index]
    first: u32,
    second: u32,
    third: u32,
}

fn main() {
    let mut my_struct = MyStruct::default();

    // The name of the field we want to index
    // Might come from user input for example
    let name = "second";

    // Use NameIndex::get_ref_mut to get a mutable
    // reference to our field
    let field_ref: &mut u32 =
        NameIndex::get_ref_mut(&mut my_struct, name)
        .expect("second is a field of MyStruct");

    *field_ref = 5;

    assert_eq!(my_struct.second, 5);
}

For the previous example the NameIndex derive creates the following (simplified1) code:

impl NameIndex<u32> for MyStruct {
    fn get_ref_mut(&mut self, name: &str) -> Option<&mut u32> {
        match name {
            "first" => Some(&mut self.first),
            "second" => Some(&mut self.second),
            "third" => Some(&mut self.third),
            _ => None,
        }
    }
    // -- snip --
}

§Second Example

This example is supposed to illustrate how NameIndexCopy can be used to save some redundant typing when the generic type of NameIndex implements std::marker::Copy.

use name_index::{NameIndex, NameIndexCopy};

#[derive(NameIndex)]
struct MyStruct {
    // When no `#[index]` attribute is given, the first field is
    // automatically chosen as the reference.
    first: u32,
    second: u32,
    third: u32,
}

fn main() {
    let mut my_struct = MyStruct {
        first: 1,
        second: 2,
        third: 3,
    };

    // We can use NameIndexCopy<u32> here because NameIndexCopy<T>
    // is automatically implemented for NameIndex<T> when T: Copy

    // Get the value of my_struct.third
    let val: u32 = NameIndexCopy::get(&my_struct, "third")
        .expect("'third' is a field of MyStruct");

    assert_eq!(val, my_struct.third);

    // Set the value of my_struct.first to 7
    NameIndexCopy::set(&mut my_struct, "first", 7)
        .expect("'first' is a field of MyStruct");

    assert_eq!(my_struct.first, 7);
}

  1. Only the NameIndex::get_ref_mut function is implemented here for clarity. 

Traits§

NameIndex
Struct field access trait
NameIndexCopy
Struct primitive field access trait

Type Aliases§

Field
Named reference to a struct field
FieldMut
Named mutable reference to a struct field

Derive Macros§

NameIndex
Macro to automatically derive NameIndex