Skip to content

Instantly share code, notes, and snippets.

@koivunej
Last active February 16, 2017 13:31
Show Gist options
  • Save koivunej/68321c230287f95f88816c278d721d16 to your computer and use it in GitHub Desktop.
Save koivunej/68321c230287f95f88816c278d721d16 to your computer and use it in GitHub Desktop.
Test case for bad decode
extern crate quick_protobuf;
// enum OperationResult
// {
// Success = 0;
// PrepareTimeout = 1;
// CommitTimeout = 2;
// ForwardTimeout = 3;
// WrongExpectedVersion = 4;
// StreamDeleted = 5;
// InvalidTransaction = 6;
// AccessDenied = 7;
// }
//
// message WriteEventsCompleted {
// required OperationResult result = 1;
// optional string message = 2;
// required int32 first_event_number = 3;
// required int32 last_event_number = 4;
// optional int64 prepare_position = 5;
// optional int64 commit_position = 6;
// }
mod messages {
use std::io::Write;
use std::borrow::Cow;
use quick_protobuf::{MessageWrite, BytesReader, Writer, Result};
use quick_protobuf::sizeofs::*;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum OperationResult {
Success = 0,
PrepareTimeout = 1,
CommitTimeout = 2,
ForwardTimeout = 3,
WrongExpectedVersion = 4,
StreamDeleted = 5,
InvalidTransaction = 6,
AccessDenied = 7,
}
impl Default for OperationResult {
fn default() -> Self {
OperationResult::Success
}
}
impl From<i32> for OperationResult {
fn from(i: i32) -> Self {
match i {
0 => OperationResult::Success,
1 => OperationResult::PrepareTimeout,
2 => OperationResult::CommitTimeout,
3 => OperationResult::ForwardTimeout,
4 => OperationResult::WrongExpectedVersion,
5 => OperationResult::StreamDeleted,
6 => OperationResult::InvalidTransaction,
7 => OperationResult::AccessDenied,
_ => Self::default(),
}
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct WriteEventsCompleted<'a> {
pub result: Option<OperationResult>,
pub message: Option<Cow<'a, str>>,
pub first_event_number: i32,
pub last_event_number: i32,
pub prepare_position: Option<i64>,
pub commit_position: Option<i64>,
}
impl<'a> WriteEventsCompleted<'a> {
pub fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
let mut msg = Self::default();
while !r.is_eof() {
match r.next_tag(bytes) {
Ok(8) => msg.result = Some(r.read_enum(bytes)?),
Ok(18) => msg.message = Some(r.read_string(bytes).map(Cow::Borrowed)?),
Ok(24) => msg.first_event_number = r.read_int32(bytes)?,
Ok(32) => msg.last_event_number = r.read_int32(bytes)?,
Ok(40) => msg.prepare_position = Some(r.read_int64(bytes)?),
Ok(48) => msg.commit_position = Some(r.read_int64(bytes)?),
Ok(t) => {
r.read_unknown(bytes, t)?;
}
Err(e) => return Err(e),
}
}
Ok(msg)
}
}
impl<'a> MessageWrite for WriteEventsCompleted<'a> {
fn get_size(&self) -> usize {
0 + self.result.as_ref().map_or(0, |m| 1 + sizeof_varint(*(m) as u64)) +
self.message.as_ref().map_or(0, |m| 1 + sizeof_len((m).len())) +
1 + sizeof_varint(*(&self.first_event_number) as u64) + 1 +
sizeof_varint(*(&self.last_event_number) as u64) +
self.prepare_position.as_ref().map_or(0, |m| 1 + sizeof_varint(*(m) as u64)) +
self.commit_position.as_ref().map_or(0, |m| 1 + sizeof_varint(*(m) as u64))
}
fn write_message<W: Write>(&self, w: &mut Writer<W>) -> Result<()> {
if let Some(ref s) = self.result {
w.write_with_tag(8, |w| w.write_enum(*s as i32))?;
}
if let Some(ref s) = self.message {
w.write_with_tag(18, |w| w.write_string(&**s))?;
}
w.write_with_tag(24, |w| w.write_int32(*&self.first_event_number))?;
w.write_with_tag(32, |w| w.write_int32(*&self.last_event_number))?;
if let Some(ref s) = self.prepare_position {
w.write_with_tag(40, |w| w.write_int64(*s))?;
}
if let Some(ref s) = self.commit_position {
w.write_with_tag(48, |w| w.write_int64(*s))?;
}
Ok(())
}
}
}
use messages::*;
#[test]
fn test_decoding_example() {
let input = vec![8u8, 0, 24, 30, 32, 39, 40, 132, 214, 188, 86, 48, 132, 214, 188, 86];
let mut reader = ::quick_protobuf::reader::BytesReader::from_bytes(&input);
let actual = reader.read_message(&input, WriteEventsCompleted::from_reader).unwrap();
assert_eq!(actual, WriteEventsCompleted {
result: Some(OperationResult::Success),
message: None,
first_event_number: 30,
last_event_number: 39,
prepare_position: Some(181349124),
commit_position: Some(181349124)
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment