0

I've generated an Index struct out of flatbuffers IDL schema and the building code was generated by flatc compiler as follows:

#[inline]
pub fn get_root_as_index<'a>(buf: &'a [u8]) -> Index<'a> {
  flatbuffers::get_root::<Index<'a>>(buf)
}

It means the created Index lives only in 'a and i have to care about who owns buf. I'm trying to pass ownership to Index together with buf and i don't understand how to make it idiomatic in Rust:

pub struct Arena<'a> {
    filter_factory: Box<dyn TFilterFactory<'a> + 'a>,
    matcher: Box<dyn TMatcher<'a> + 'a>,
}

pub struct Context<'a> {
    buffer: Vec<u8>,
    arena: Arena<'a>
}

impl<'a> Arena<'a> {
    pub fn new(file_path: &'a str) -> Context {
        let mut file = File::open(file_path).unwrap();
        let mut buffer = Vec::new();
        file.read_to_end(&mut buffer).expect("File reading failed");
        let index = get_root_as_index(&buffer[..]);
        Context{
            buffer,
            arena: Arena {
                filter_factory: Box::new(FilterFactory::new()),
                matcher: Box::new(Matcher::new(
                    Box::new(FlatBuffersIndex::new(index)),
                    Box::new(FiltersLazyDataRegistry::new())
                ))
            }
        }
    }
}

How can i pass the ownership of Index together with buf so i don't have to care about buf (assuming the owner of Index also owns buf)?

I've tried to make a buffer a member of Arena struct, borrow it when creating an Index instance, but later i can't move this new struct.

PS. Ideally i'd love to have an Index that owns it's buffer (so i can care about only 1 instance owner), but that's not how the code is generated.

4ntoine
  • 19,816
  • 21
  • 96
  • 220
  • 2
    Does this answer your question: [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/q/32300132) See the "How to fix" part. – kmdreko May 01 '21 at 20:47
  • That's useful to understand the rootcause. However, it's unclear how to fix it. Option #1 "not put into single struct". I need to put them together as eventually i need to store just 1 pointer (to the struct that owns both for instance). Not working. Option #2 "owning_ref". Let's say i keep buffer as an object, Index holds the reference to a buffer but it's not a reference itself. Trying to hold a reference to `Index` will cause `ref to a temp value` the code `let or = OwningRef::new(buffer); let or = or.map(|b| &get_root_as_index(&b[..]));`. – 4ntoine May 02 '21 at 09:48
  • Option #3 "setting none, then creating an instance and then setting some". That's not working as i will have to move it with `Box::into_raw` to get the raw pointer. Option #4 "pinning". That can possible work. What's the suggested solution? – 4ntoine May 02 '21 at 09:48

0 Answers0