Mapping key value pairs into a Struct?


#1

I have a string which contains some key-value pairs

"timestamp=1464707663 sequence=55261 action=LOAD info=krondor"

which I have processed using regex and extracted into a Vector of Strings

[ "timestamp=1464707663", "sequence=55261", "action=LOAD", "info=krondor" ]

What I now want to do is be able to take the values for each of these and place them into the appropriate place in my structure, preferably without having to write out match statements for each possible key value tuple.

struct SystemEvent {
    timestamp: u32,
    sequence: u32,
    action: String,
    info: String    
}

I’m not sure if this is even possible. I had thought that std::iter::FromIterator might be of use here?


#2

You could probably process them a little bit further, splitting those equals signs and turn them in to a Vector of tuples:

[ ("timestamp", "1464707663"), ("sequence", "55261"), ("action", "LOAD"), ("info", "krondor") ]

and then you can match on just the field name, e.g.

for (f, v) in events.iter() {
    match f {
        "timestamp": event.timestamp = u32::from(v),
        ...
    }
}

(I didn’t actually try to compile that, so it’s probably at least somewhat wrong).


#3

To do this fully automatically, you’d need the rustc_serialize crate. That’s a bit heavyweight, though. In some cases it might be easier to use macro_rules!. For example, this macro:

macro_rules! convert_fields {
    ($key:expr, $val:expr, $struc:expr, ($($field:ident),*)) => {
        match $key {
            $(
                stringify!($field) => $struc.$field = MyConvertTrait::convert($val),
            )*
        }
    }
}

fn test() {
    convert_fields!(key, val, struc, (one, two, three));
}

expands to:

fn test() {
    match key {
        "one" => struc.one = MyConvertTrait::convert(val),
        "two" => struc.two = MyConvertTrait::convert(val),
        "three" => struc.three = MyConvertTrait::convert(val),
    };
}

for a hypothetical trait MyConvertTrait that would look something like the currently unstable TryFrom.


#4

Thank you @ahwatts and @comex, the ideas are much appreciated.