1#![warn(missing_docs)]
42
43use std::boxed::Box;
44use std::io;
45use std::result;
46use std::fmt;
47use self::codec::Codec;
48use self::bitio::ByteCount;
49use self::bitio::BitReader;
50use self::bitio::BitWriter;
51
52pub mod bitio;
53pub mod codec;
54pub mod model;
55
56pub enum Error {
58 Eof,
60 InvalidInput,
62 IoError(io::Error),
64}
65
66impl fmt::Display for Error {
67 fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
68 match *self {
69 Error::Eof => f.write_str("Unexpected end of file"),
70 Error::InvalidInput => f.write_str("Invalid data found while processing input"),
71 Error::IoError(ref e) => f.write_fmt(format_args!("I/O error: {}", e)),
72 }
73 }
74}
75
76impl fmt::Debug for Error {
77 fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
78 match *self {
79 Error::Eof => f.write_str("Eof"),
80 Error::InvalidInput => f.write_str("InvalidInput"),
81 Error::IoError(ref e) => f.write_fmt(format_args!("IoError({:?})", e)),
82 }
83 }
84}
85
86#[cfg(test)]
87impl PartialEq<Error> for Error {
88 fn eq(&self, other: &Error) -> bool {
89 match *self {
90 Error::Eof => match *other { Error::Eof => true, _ => false },
91 Error::InvalidInput => match *other { Error::InvalidInput => true, _ => false },
92 Error::IoError(_) => match *other { Error::IoError(_) => true, _ => false },
93 }
94 }
95}
96
97pub type Result<T> = result::Result<T, Error>;
99
100pub fn compress(istream: &mut io::Read, ostream: &mut io::Write, model: Box<model::Model>) -> Result<(u64, u64)> {
103 let mut codec = Codec::new(model);
104 let mut input = BitReader::new(istream);
105 let mut output = BitWriter::new(ostream);
106
107 try!(codec.compress_stream(&mut input, &mut output));
108 return Ok((input.get_count(), output.get_count()));
109}
110
111pub fn decompress(istream: &mut io::Read, ostream: &mut io::Write, model: Box<model::Model>) -> Result<(u64, u64)> {
114 let mut codec = Codec::new(model);
115 let mut input = BitReader::new(istream);
116 let mut output = BitWriter::new(ostream);
117
118 try!(codec.decompress_stream(&mut input, &mut output));
119 return Ok((input.get_count(), output.get_count()));
120}
121
122#[cfg(test)]
123mod tests {
124 use super::Error::*;
125 use std::io;
126
127 macro_rules! assert_ne {
128 ($a:expr, $b:expr) => ($a != $b)
129 }
130
131 #[test]
132 fn error_eq() {
133 assert_eq!(Eof, Eof);
134 assert_eq!(InvalidInput, InvalidInput);
135 assert_eq!(IoError(io::Error::new(io::ErrorKind::Other, "Other")), IoError(io::Error::new(io::ErrorKind::NotFound, "NotFound")));
136 assert_ne!(Eof, InvalidInput);
137 assert_ne!(InvalidInput, IoError(io::Error::new(io::ErrorKind::Other, "Other")));
138 assert_ne!(IoError(io::Error::new(io::ErrorKind::NotFound, "NotFound")), Eof);
139 }
140}