use std::num::NonZeroU32;
use winnow::{Parser, token::any};
use super::{ByteOrder, Input, PResult, ParseError};
use crate::message::{Flags, PrimaryHeader, Type};
pub(super) fn primary_header<O: ByteOrder>(input: &mut Input<'_>) -> PResult<PrimaryHeader> {
(
any,
any.try_map(message_type),
any.map(Flags::from_bits_retain),
any,
O::u32,
O::u32.try_map(serial_num),
)
.map(
|(_, msg_type, flags, protocol_version, body_len, serial_num)| {
PrimaryHeader::from_parts(
O::ENDIAN_SIG,
msg_type,
flags,
protocol_version,
body_len,
serial_num,
)
},
)
.parse_next(input)
}
fn message_type(code: u8) -> Result<Type, ParseError> {
match code {
1 => Ok(Type::MethodCall),
2 => Ok(Type::MethodReturn),
3 => Ok(Type::Error),
4 => Ok(Type::Signal),
_ => Err(ParseError::MessageType),
}
}
fn serial_num(serial_num: u32) -> Result<NonZeroU32, ParseError> {
NonZeroU32::new(serial_num).ok_or(ParseError::Serial)
}