use super::*;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub enum DocMessage {
#[cfg_attr(test, proptest(skip))]
Step1(Vec<u8>),
Step2(Vec<u8>),
Update(Vec<u8>),
}
const DOC_MESSAGE_STEP1: u64 = 0;
const DOC_MESSAGE_STEP2: u64 = 1;
const DOC_MESSAGE_UPDATE: u64 = 2;
pub fn read_doc_message(input: &[u8]) -> IResult<&[u8], DocMessage> {
let (tail, step) = read_var_u64(input)?;
match step {
DOC_MESSAGE_STEP1 => {
let (tail, sv) = read_var_buffer(tail)?;
Ok((tail, DocMessage::Step1(sv.into())))
}
DOC_MESSAGE_STEP2 => {
let (tail, update) = read_var_buffer(tail)?;
Ok((tail, DocMessage::Step2(update.into())))
}
DOC_MESSAGE_UPDATE => {
let (tail, update) = read_var_buffer(tail)?;
Ok((tail, DocMessage::Update(update.into())))
}
_ => Err(nom::Err::Error(Error::new(input, ErrorKind::Tag))),
}
}
pub fn write_doc_message<W: Write>(buffer: &mut W, msg: &DocMessage) -> Result<(), IoError> {
match msg {
DocMessage::Step1(sv) => {
write_var_u64(buffer, DOC_MESSAGE_STEP1)?;
write_var_buffer(buffer, sv)?;
}
DocMessage::Step2(update) => {
write_var_u64(buffer, DOC_MESSAGE_STEP2)?;
write_var_buffer(buffer, update)?;
}
DocMessage::Update(update) => {
write_var_u64(buffer, DOC_MESSAGE_UPDATE)?;
write_var_buffer(buffer, update)?;
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_doc_message() {
let messages = [
DocMessage::Step1(vec![0x01, 0x02, 0x03]),
DocMessage::Step2(vec![0x04, 0x05, 0x06]),
DocMessage::Update(vec![0x07, 0x08, 0x09]),
];
for msg in messages {
let mut buffer = Vec::new();
write_doc_message(&mut buffer, &msg).unwrap();
let (tail, decoded) = read_doc_message(&buffer).unwrap();
assert_eq!(tail.len(), 0);
assert_eq!(decoded, msg);
}
{
let mut buffer = Vec::new();
let msg = DocMessage::Step1(vec![0x01, 0x02, 0x03]);
write_doc_message(&mut buffer, &msg).unwrap();
buffer[0] = 0xff; let res = read_doc_message(&buffer);
match res.as_ref().unwrap_err() {
nom::Err::Error(error) => assert_eq!(error.code, ErrorKind::Tag),
_ => panic!("Expected error ErrorKind::Tag, but got {:?}", res),
}
}
}
}