0

I am trying to write a wrapper function for read a string that contains Vec[u8] (that are really just MsgPacks) and convert them to native rust structs, my code looks like this

use rmp_serde::{decode, from_slice};
use serde::Deserialize;

#[derive(Debug)]
pub enum MsgPackParseErr {
    ParseIntError,
    SerdeError,
}

impl From<std::num::ParseIntError> for MsgPackParseErr {
    fn from(_e: std::num::ParseIntError) -> Self {
        return Self::ParseIntError;
    }
}

impl From<decode::Error> for MsgPackParseErr {
    fn from(_e: decode::Error) -> Self {
        return Self::SerdeError;
    }
}

pub fn msgpack_from_byte_string<'b, T>(raw: String) -> Result<T, MsgPackParseErr>
where
    T: Deserialize<'b>,
{
    let parsing_string: Result<Vec<u8>, _> = raw.split(" ").map(|x| x.parse()).collect();
    let parsed_string = parsing_string?;
    let parsing_obj = from_slice(&parsed_string);
    Ok(parsing_obj?)
}

But I am getting the error

temporary value dropped while borrowed

creates a temporary which is freed while still in use

For lines 23 to 28 i.e.

let parsing_obj = from_slice(&parsed_string);
    Ok(parsing_obj?)

I have no idea what I am doing wrong here...

asosnovsky
  • 2,158
  • 3
  • 24
  • 41

1 Answers1

1

Your error comes from the fact that T: Deserialize<'b> in your code constrains T to live only as long as the lifetime 'b which in turn means it can't outlive whatever the input to from_slice was (otherwise it would be a use after free error).

pub fn msgpack_from_byte_string<'b, T>(raw: String) -> Result<T, MsgPackParseErr>
where
    T: Deserialize<'b>

So why can't your serialized object be alive longer than the data associated with it? If possible, serde avoids the copy of the input data and allocation of extra fields by directly referencing the input buffer. This is also explained in more detail in the serde manual chapter about lifetimes. Note that serde has also other traits that may be more appropriate for your use-case and are not constrained to the lifetime of the input (e.g., DeserializeOwned).

zgerd
  • 1,080
  • 8
  • 17