use super::state::State;
use crate::{decoder::Event, error::Error, field::WireType};
#[derive(Debug)]
pub(super) struct Decoder {
wire_type: WireType,
remaining: usize,
}
impl Decoder {
pub fn new(wire_type: WireType, length: usize) -> Self {
debug_assert!(
wire_type.is_dynamically_sized(),
"not a dynamically sized wire type: {:?}",
wire_type
);
Self {
wire_type,
remaining: length,
}
}
pub fn decode<'a>(self, input: &mut &'a [u8]) -> Result<(State, Option<Event<'a>>), Error> {
if input.is_empty() {
return Ok((self.into(), None));
}
let chunk_size = if input.len() >= self.remaining {
self.remaining
} else {
input.len()
};
let bytes = &input[..chunk_size];
*input = &input[chunk_size..];
let remaining = self.remaining.checked_sub(chunk_size).unwrap();
let event = Event::ValueChunk {
wire_type: self.wire_type,
bytes,
remaining,
};
let new_state = State::transition(&event);
Ok((new_state, Some(event)))
}
}
impl From<Decoder> for State {
fn from(decoder: Decoder) -> State {
State::Body(decoder)
}
}