use super::state::State;
use crate::{
decoder::{
vint64::{self, zigzag},
Event,
},
error::Error,
field::WireType,
};
#[derive(Debug)]
pub(super) struct Decoder {
decoder: vint64::Decoder,
wire_type: WireType,
}
impl Decoder {
pub fn new(wire_type: WireType) -> Self {
Self {
decoder: vint64::Decoder::new(),
wire_type,
}
}
pub fn decode<'a>(mut self, input: &mut &'a [u8]) -> Result<(State, Option<Event<'a>>), Error> {
if let Some(value) = self.decoder.decode(input)? {
let event = match self.wire_type {
WireType::False => Event::Bool(false),
WireType::True => Event::Bool(true),
WireType::UInt64 => Event::UInt64(value),
WireType::SInt64 => Event::SInt64(zigzag::decode(value)),
WireType::Sequence => Event::SequenceHeader {
wire_type: WireType::from_unmasked(value),
length: (value >> 4) as usize,
},
wire_type => {
debug_assert!(
wire_type.is_dynamically_sized(),
"not a dynamically sized wire type: {:?}",
wire_type
);
Event::LengthDelimiter {
wire_type,
length: value as usize,
}
}
};
let new_state = State::transition(&event);
Ok((new_state, Some(event)))
} else {
Ok((State::Value(self), None))
}
}
}