Open vext01 opened 1 year ago
I thought this may be possible with ctx
, but it can only see previously parsed fields.
You could achieve it with a reader.
We could add a __deku
variable that could be used.
How would I access the parent parser in a reader
though?
use deku::{
bitvec::{BitSlice, Msb0},
prelude::*,
};
#[derive(DekuRead, Debug, PartialEq, Eq)]
struct Parent {
#[deku(bytes = "1")]
num: usize,
#[deku(reader = "Parent::read(deku::rest, *num)")]
#[deku(count = "num")]
subs: Vec<Sub>,
}
impl Parent {
fn read(
rest: &BitSlice<u8, Msb0>,
count: usize,
) -> Result<(&BitSlice<u8, Msb0>, Vec<Sub>), DekuError> {
let mut subs = Vec::with_capacity(count);
let mut left_rest = rest;
for n in 0..count {
let (l_rest, mut sub) = Sub::read(left_rest, ())?;
sub.idx = n;
println!("{:?}", sub);
subs.push(sub);
left_rest = l_rest;
}
Ok((left_rest, subs))
}
}
#[derive(DekuRead, Debug, PartialEq, Eq)]
struct Sub {
#[deku(skip)]
idx: usize,
a: u8,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_00() {
let bytes: &[u8] = &[0x02, 0x0f, 0xf0];
let parent = Parent::try_from(bytes).unwrap();
assert_eq!(
parent,
Parent {
num: 2,
subs: vec![Sub { idx: 0, a: 0x0f }, Sub { idx: 1, a: 0xf0 }]
}
)
}
}
Thanks. Right, so you have to manually parse the sub-struct.
It would indeed be useful to have some way to do it without that burden.
perhaps for a Vec field, you pass down some implicit context or similar?
Best explained by example:
How can I get each
Sub::idx
to be set to the index of theSub
inParent::subs
?Cheers