use super::seen_keys::SeenKeys;
use crate::binary::{DecodeError, Decoder, NEW_STRING};
impl Decoder<'_> {
pub(in crate::wire::binary) fn shape_spec(&mut self) -> Result<usize, DecodeError> {
let marker = self.varint()?;
if marker & NEW_STRING == 0 {
let shape = usize::try_from(marker >> 1).unwrap_or(usize::MAX);
return if shape < self.shapes.len() {
Ok(shape)
} else {
Err(self.error(format!("shape {shape} isn't defined")))
};
}
let left = self.b.len() - self.i;
let n = match usize::try_from(marker >> 1) {
Ok(0) => return Err(self.error("a shape with no keys")),
Ok(n) if n <= left => n,
_ => {
let n = marker >> 1;
return Err(self.error(format!("length {n} past the end ({left} bytes left)")));
}
};
let mut seen = SeenKeys::default();
for _ in 0..n {
let at = self.i;
let string = self.string_index()?;
if !seen.insert(self.strings[string]) {
return Err(DecodeError::duplicate_key(self.strings[string], at));
}
self.shapes.push_key(string);
}
Ok(self.shapes.seal())
}
pub(in crate::wire::binary) fn shape_width(&self, shape: usize) -> Result<usize, DecodeError> {
let n = self.shapes.width(shape);
let left = self.b.len() - self.i;
if n <= left {
Ok(n)
} else {
Err(self.error(format!("length {n} past the end ({left} bytes left)")))
}
}
}