Is it possible to generalize a type using rmp serde?

Hello everyone,

I have just started writing a metasploit client, that uses messagepack to deserialize an object using rmp-serde. I would like to know if I can refactor my code to generalize the data type that I am returning, rather than using if statements to return a specific value of an enum. The code in question is

if method == "auth.login" || method == "core.version" {
   let de_str = Deserialize::deserialize(&mut de).unwrap();
        
    Ok(SessionMapType::SM(de_str))
}
else {
    let de_str = Deserialize::deserialize(&mut de).unwrap();
        
    Ok(SessionMapType::SMV(de_str))
}

from https://github.com/ecks/msf-client/blob/master/src/lib.rs.

I know that the method “auth.login” and “core.version” return a HashMap<String, String>, but that “module.exploits” returns HashMap<String, Vec>. I was thinking that I could have a function definition something like

pub fn execute<T: Deserialize, 'a>(&mut self, method: &'a str, args: Vec<&'a str>) -> Res<T> so rather than an enum, it returns a generlized type. Then in the authenticate function I could have let ret: Res<SessionMap> self.execute("auth.login", args), for instance. and do the same with the other functions that call self.execute.

However I am not sure if that is even possible, and whether I would have to make SessionMap and SessionMapVec implement the Deserialize trait. I have played around with different syntax but am not sure if I’m headed down the right back. If necessary, I can just leave the if statements in there.

If you don’t need MessagePack specifically, this is just a rube goldberg machine.

When dealing with multiple types dynamically, you can tackle that directly:

  1. Use enum Session { WithVec(HashMap<String, Vec>), WithString(HashMap<String, String>) }
  2. Use a trait
trait Session {/* add useful methods here */}; 
impl Session for HashMap<String, Vec> {} 
impl Session for HashMap<String, String> {}

fn login() -> Box<dyn Session> {
   Box::new(HashMap::new())
}
1 Like

Hi kornel,

Thanks for the reply. I believe I am currently doing it the first way with enums. However the second way I don’t think will remove of the if statements either since I have to still make Box out each possible type before returning it.

  • ecks