Lifespan/Borrowed Value Error for Deserializer

I have trouble putting my problem into words so please bare with me until the end.

I want to be able to store a Deserializer type variable in a struct from the rmp-serde library. I also want to replace it with a new deserializer various times. Something like this:

struct MyStruct<R> {
    pub de: Deserializer<R>
}

impl <R> MyStruct<R> {
    pub fn some_process(&mut self) {
        self.de = get_new_deserializer();  // This line is essentially my exact problem
        // OR
        // let buf = get_buffer;  // Returns &[u8] or maybe Vec<u8>
        // self.de = Deserializer::new(&buf[..]);
        // OR
        // set_new_deserializer(&mut self);
    }
}

The problem is that I always got lifetime issues so I tried to fix that by adding <'a> to my struct and removed generics by hardcoding the type (to make it easier for me). I converted it to the best of my ability to Rust Playground to show case the problem with my code removing everything unnecessary. I reformatted it many times to try and fix the problem, this is just the most recent attempt I made. I also tried passing the struct and setting it in the function itself.

I want to pass into the deserializer a slice of my buffer variable which could either be a Vec<u8> or a &[u8].

Deserializer::new(&buf[..]);

I tried cloning and copying the variable, but I couldn't get it to work. I know my problem isn't anything to do with the library, I just don't know how to reproduce the same problem. I am unsure what to do and the various solutions I have read did not help me solve my problem either.

I am just having a hard time pinpointing exactly what I am doing wrong, whether it is with my implementation of lifetime variables, or misuse of borrowed values I don't know. Any help would be greatly appreciated, thank you for reading this mess.

The problem with something like Deserializer::new(&buf[..]); is that the data needs to live somewhere. Currently it would be dropped after the Ok block. It could live in self.data, but as I understand it self-referential structs in Rust are pretty tricky, so it's better to make it so Deserializer owns it if possible.

The first idea might be to just put the Vec<u8> into the Deserializer but that doesn't work:

8 |     pub de: Deserializer<ReadReader<Vec<u8>>>,
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::io::Read` is not implemented for `std::vec::Vec<u8>

To turn a Vec into something that implements Read, we can use std::io::Cursor. Let me know if the code below works out for you.

use rmp_serde::decode::Deserializer;
use rmp_serde::decode::ReadReader;
use std::io::Cursor;

struct MyStruct {
    pub de: Deserializer<ReadReader<Cursor<Vec<u8>>>>,
}

impl MyStruct {
    pub fn some_implementation(&mut self) {
        match some_process() {
            Ok(buf) => {
                self.de = Deserializer::new(Cursor::new(buf));
            }
            Err(_) => {}
        }
    }
}

pub fn main() {}

fn some_process() -> Result<Vec<u8>, ()> {
    let mut buf: Vec<u8> = Vec::new();
    buf.push(1);
    buf.push(2);
    return Ok(buf);
}
1 Like

Thank you so much, this seems to have worked for me in regards to the compiler shouting at me.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.