use crate::{decode::*, wire::*, *};
#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct MsgDecoder<'a> {
pub wire_decoder: WireDecoder<'a>,
}
impl<'a> MsgDecoder<'a> {
pub fn new(data: &'a [u8]) -> MsgDecoder<'a> {
MsgDecoder {
wire_decoder: WireDecoder { data },
}
}
fn next_inner(&mut self) -> Result<MsgRecordRef<'a>, DecodeError> {
let tag = self.wire_decoder.read_var_uint32()?;
let field_number = FieldNumber(tag >> 3);
let wire_type = tag & 0b111;
let value = match wire_type {
0 => WireValueRef::VarInt(WireVarInt::from_raw(self.wire_decoder.read_var_uint64()?)),
1 => WireValueRef::I64(WireI64(self.wire_decoder.read_fixed64()?)),
2 => {
let len: usize = self.wire_decoder.read_var_uint32()? as usize;
let data = self.wire_decoder.take_nbyte(len)?;
WireValueRef::Len(WireLenRef { data })
}
3 => WireValueRef::SGroup,
4 => WireValueRef::EGroup,
5 => WireValueRef::I32(WireI32(self.wire_decoder.read_fixed32()?)),
unknown => {
return Err(DecodeError::UnknownWireType(unknown));
}
};
Ok(MsgRecordRef {
field_number,
value,
})
}
}
impl<'a> Iterator for MsgDecoder<'a> {
type Item = Result<MsgRecordRef<'a>, DecodeError>;
fn next(&mut self) -> Option<Result<MsgRecordRef<'a>, DecodeError>> {
if self.wire_decoder.data.is_empty() {
return None;
}
match self.next_inner() {
Err(err) => {
self.wire_decoder.data = &[];
Some(Err(err))
}
other => Some(other),
}
}
}