1#![warn(missing_docs,
2 missing_debug_implementations, missing_copy_implementations,
3 trivial_casts, trivial_numeric_casts,
4 unstable_features,
5 unused_import_braces, unused_qualifications)]
6
7mod file;
12mod multicast;
13
14use std::convert::From;
15use std::{error, fmt};
16
17#[derive(Copy, Clone, Debug, PartialEq, Eq)]
19pub enum Error {
20 CorruptSegmentHeader,
22 CorruptMsgHeader,
24 InsufficientLength(usize),
27 IoError(std::io::ErrorKind),
30}
31
32impl fmt::Display for Error {
33 fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
34 write!(f, "{:?}", self)
35 }
36}
37
38impl error::Error for Error {
39 fn description(&self) -> &str {
40 match *self {
41 Error::CorruptSegmentHeader => "corrupted segment header",
42 Error::CorruptMsgHeader => "corruped message header",
43 Error::InsufficientLength(..) => "insufficient length",
44 Error::IoError(..) => "I/O error",
45 }
46 }
47
48 fn cause(&self) -> Option<&dyn error::Error> {
49 None
50 }
51}
52
53impl From<std::io::Error> for Error {
54 fn from(err: std::io::Error) -> Error {
55 Error::IoError(err.kind())
56 }
57}
58
59pub type Result<T> = std::result::Result<T, Error>;
61
62pub trait Reader {
64 fn read(&mut self) -> Result<Option<Vec<u8>>>;
68}
69
70pub trait Writer {
72 fn write(&mut self, buf: &[u8]) -> Result<()>;
74}
75
76pub use file::{FileReader, FileWriter};
77pub use multicast::{MulticastReader, MulticastWriter};
78
79#[cfg(test)]
80mod tests {
81 use ::std;
82 use super::*;
83
84 #[test]
85 fn reader_return_err_on_corrupted_header() {
86 let empty = std::io::empty();
87 assert_eq!(Error::CorruptSegmentHeader, FileReader::new(empty).err().unwrap());
88 let wrong_header = &b"DFSM"[..];
89 assert_eq!(Error::CorruptSegmentHeader, FileReader::new(wrong_header).err().unwrap());
90 }
91
92 #[test]
93 fn reader_read_one_message() {
94 let data = &b"DFSN\x05\0\0\0hello"[..];
95 assert_eq!(b"hello"[..], FileReader::new(data).unwrap().read().unwrap().unwrap()[..]);
96 }
97
98 #[test]
99 fn reader_return_err_on_truncated_data() {
100 let truncated_data = &b"DFSN\x05\0\0\0hell"[..];
101 assert_eq!(Err(Error::InsufficientLength(1)), FileReader::new(truncated_data).unwrap().read());
102 }
103
104 #[test]
105 fn reader_return_err_on_corrupted_message_header() {
106 let data_with_corrupted_header = &b"DFSN\x05\0\0"[..];
107 assert_eq!(Err(Error::CorruptMsgHeader), FileReader::new(data_with_corrupted_header).unwrap().read());
108 }
109
110 #[test]
111 fn writer_return_err_when_writing_header_with_short_length() {
112 let mut buffer = [0u8;3];
113 assert_eq!(Error::CorruptSegmentHeader, FileWriter::new(&mut buffer[..]).err().unwrap());
114 }
115
116 #[test]
117 fn writer_write_one_message() {
118 let message: &[u8] = b"hello";
119 let mut writer: Vec<u8> = vec![];
120 assert!(FileWriter::new(&mut writer).unwrap().write(message).is_ok());
121 assert_eq!(b"DFSN\x05\0\0\0hello".as_ref(), &writer[..]);
122 }
123}