Replacing indices with references during parsing.
vext01 opened this issue · comments
Hi,
We have a parser for a compiler IR where we use indices for the (immutable) on-disk serialisation format, and we read it in with Deku.
We'd like to be able to convert the indices to immutable references for ease of use once parsing is complete.
I mocked this up:
#![allow(dead_code)]
use deku::prelude::*;
#[deku_derive(DekuRead)]
#[derive(Debug)]
struct TopLevel {
num_foos: usize,
#[deku(count = "num_foos")]
foos: Vec<Foo>,
num_bars: usize,
#[deku(count = "num_bars")]
bars: Vec<Bar>,
}
#[deku_derive(DekuRead)]
#[derive(Debug)]
struct Foo {
val: u8,
}
#[deku_derive(DekuRead)]
#[derive(Debug)]
struct Bar {
#[deku(temp)]
foo_idx: usize,
// XXX: How to we convert the `foo_idx` to a reference to foos[0] in the super-struct?
//foo_ref: &'a Foo,
}
fn main() {
// Assume little-endian.
let data: Vec<u8> = vec![
// num_foos=1
1, 0, 0, 0, 0, 0, 0, 0,
// foos[0]
// val
0xaa,
// num_bars=1
1, 0, 0, 0, 0, 0, 0, 0,
// bars[0]
// foo_idx
0, 0, 0, 0 ,0, 0, 0, 0
];
let (_rest, mut val) = TopLevel::from_bytes((data.as_ref(), 0)).unwrap();
dbg!(&val);
}
Is there a way to convert the foo_idx
into a reference to foos[0]
during parsing?
I can imagine an API that perhaps looks like this (or similar):
#[deku_derive(DekuRead)]
#[deku(endian = "big")]
#[derive(Debug)]
struct Bar {
#[deku(temp)]
foo_idx: usize,
#[deku(skip, map = "|_| -> &deku_parent.foos[foo_idx]")]
foo_ref: &Foo,
}
Supposing deku had the deku_parent
thing (which can probably be done already, albeit verbosely, with ctx
), something tells me that this wouldn't sit well with the borrow checker. The parent struct is still being parsed and therefore needs to be mutable, but we are making immutable references to it.
skip
ping foo_ref
also requires &Foo
to have a Default
, which makes no sense. Maybe you'd have to use raw pointers to allow a NULL pointer...
Another option is to not to the conversion during parsing, but to post-process it, or generate some kind of "index to reference" map after the fact.
But anyway, I'm wondering, Is there an idiom for doing this kind of thing with deku?
Thanks