use super::{body, header, value};
use crate::{
decoder::Event,
error::Error,
field::{Tag, WireType},
};
#[derive(Debug)]
pub(super) enum State {
Header(header::Decoder),
Value(value::Decoder),
Body(body::Decoder),
}
impl State {
pub(super) fn decode<'a>(
self,
input: &mut &'a [u8],
last_tag: Option<Tag>,
) -> Result<(Self, Option<Event<'a>>), Error> {
match self {
State::Header(header) => header.decode(input, last_tag),
State::Value(value) => value.decode(input),
State::Body(body) => body.decode(input),
}
}
pub(super) fn transition(event: &Event<'_>) -> Self {
match event {
Event::FieldHeader(header) => value::Decoder::new(header.wire_type).into(),
Event::Bool(_) | Event::UInt64(_) | Event::SInt64(_) => State::default(),
Event::LengthDelimiter { wire_type, length } => {
if *length > 0 {
body::Decoder::new(*wire_type, *length).into()
} else {
State::default()
}
}
Event::SequenceHeader { length, .. } => {
if *length > 0 {
body::Decoder::new(WireType::Sequence, *length).into()
} else {
State::default()
}
}
Event::ValueChunk {
wire_type,
remaining,
..
} => {
if *remaining > 0 {
body::Decoder::new(*wire_type, *remaining).into()
} else {
State::default()
}
}
}
}
}
impl Default for State {
fn default() -> State {
State::Header(Default::default())
}
}
impl From<value::Decoder> for State {
fn from(decoder: value::Decoder) -> State {
State::Value(decoder)
}
}