use byteorder::{BigEndian, WriteBytesExt};
use combine::{parser::*, *};
use std::io;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct MarkedData<'a> {
pub marker: u8,
pub data: &'a [u8],
}
impl<'a> MarkedData<'a> {
pub fn parser<I: 'a>(
marker: impl Parser<Input = I, Output = u8> + 'a,
) -> impl Parser<Input = I, Output = MarkedData<'a>> + 'a
where
I: RangeStream<Item = u8, Range = &'a [u8]>,
I::Error: ParseError<I::Item, I::Range, I::Position>,
{
(byte::byte(0xFF), marker, byte::num::be_u16()).then(|(_, marker, size)| {
if size >= 2 {
range::take(size as usize - 2)
.map(move |data| Self { marker, data })
.left()
} else {
unexpected_any("16-bit big-endian size less than 2").right()
}
})
}
pub fn write<W: WriteBytesExt>(&self, writer: &mut W) -> io::Result<()> {
writer.write_u8(0xFF)?;
writer.write_u8(self.marker)?;
writer.write_u16::<BigEndian>((self.data.len() + 2) as u16)?;
writer.write_all(self.data)
}
}