fieldname-access 0.1.6

Derive macro for safe struct field access by their names in runtime
Documentation
fieldname-access-0.1.6 has been yanked.

FieldnameAccess Derive Macro

It is used to safely get values from the structure by field name when we do not know exactly which field we will need at the moment but can match it and do some actions based on other data

Practical example

Let's say we have a User structure and Crit criteria for it.

use fieldname_access::FieldnameAccess;

#[derive(FieldnameAccess)]
struct User {
    name: String,
    age: u64,
    does_love_ranni: bool, // important 
}

struct Crit {
    value: String,
    field: String,
    kind: CritKind,
}

enum CritKind {
    Contains,
    Equals,
    BiggerThan,
}

Based on this information FieldnameAccess will generate all possible types of field and methods for User struct to access them by name:

enum UserField<'a> {
	String(&'a String),
	U64(&'a u64),
	Bool(&'a bool)
}

enum UserFieldMut<'a> {
	String(&'a mut String),
	U64(&'a mut u64),
	Bool(&'a mut bool)
}

Having information on these two elements, we can determine our next steps.

let user = User {
    age: 2022,
    name: String::from("Radahn"),
    does_love_ranni: true,
};

let crits = vec![
    Crit {
        value: String::from("Ra"),
        field: String::from("name"),
        kind: CritKind::Contains,
    },
    Crit {
        value: String::from("true"),
        field: String::from("does_love_ranni"), // important
        kind: CritKind::Equals,
    },
    Crit {
        value: String::from("18"),
        field: String::from("age"),
        kind: CritKind::BiggerThan,
    },
];

let its_ok = crits.into_iter().all(|crit| {
    let user_field =
        user.field(&crit.field).expect("Criteria has wrong fieldname");
    match crit.kind {
        CritKind::Contains => match user_field {
            UserField::String(str) => str.contains(&crit.value),
            _ => panic!("Criteria has wrong value"),
        },
        CritKind::Equals => match user_field {
            UserField::String(str) => str.eq(&crit.value),
            UserField::U64(int) => int.eq(&crit.value.parse::<u64>().unwrap()),
            UserField::Bool(boolean) => {
                boolean.eq(&crit.value.parse::<bool>().unwrap())
            }
        },
        CritKind::BiggerThan => match user_field {
            UserField::U64(int) => int > &crit.value.parse::<u64>().unwrap(),
            _ => panic!("Criteria has wrong value"),
        },
    }
});
assert!(its_ok);

Also you can modify fields

if let Some(UserFieldMut::Bool(does_love_ranni)) =
    user.field_mut("does_love_ranni") // important
{
    *does_love_ranni = false; // HARAM
}
assert!(!user.does_love_ranni); //important