#[macro_use]
extern crate failure_derive;
pub use crate::lz_dict::LZDict;
use std::io;
pub mod lz_dict;
pub mod crc32;
pub mod murmur3;
#[derive(Debug, Fail)]
pub enum LZJDError {
#[fail(display = "IO error: {}", err)]
Io {
#[cause]
err: io::Error,
},
#[fail(display = "Decode error: {}", err)]
Base64 {
#[cause]
err: base64::DecodeError,
},
#[fail(display = "Bincode error: {}", err)]
Bincode {
#[cause]
err: bincode::Error,
},
#[fail(display = "Error: {}", msg)]
Msg { msg: String },
}
impl From<base64::DecodeError> for LZJDError {
fn from(err: base64::DecodeError) -> Self {
LZJDError::Base64 { err }
}
}
impl From<bincode::Error> for LZJDError {
fn from(err: bincode::Error) -> Self {
LZJDError::Bincode { err }
}
}
impl From<std::io::Error> for LZJDError {
fn from(err: std::io::Error) -> Self {
LZJDError::Io { err }
}
}
impl<'a> From<&'a str> for LZJDError {
fn from(msg: &'a str) -> Self {
LZJDError::Msg {
msg: msg.to_owned(),
}
}
}
pub type Result<T> = std::result::Result<T, LZJDError>;
#[cfg(test)]
mod tests {
use crate::crc32::CRC32BuildHasher;
use crate::*;
use std::f64::EPSILON;
#[test]
fn test_optimized_dist() {
let build_hasher = CRC32BuildHasher;
let a = b"THIS IS A TEST SEQUENCE";
let b = b"THIS IS A TEST SEQUENCE";
let c = b"totally_different";
let d = b"THIS IS A DIFFERENT TEST SEQUENCE";
let dict_a = LZDict::from_bytes_stream_lz78(a.iter().cloned(), &build_hasher);
let dict_b = LZDict::from_bytes_stream_lz78(b.iter().cloned(), &build_hasher);
let dict_c = LZDict::from_bytes_stream_lz78(c.iter().cloned(), &build_hasher);
let dict_d = LZDict::from_bytes_stream_lz78(d.iter().cloned(), &build_hasher);
let dist = dict_a.dist(&dict_b);
assert!(
dist.abs() < EPSILON, "Distance of equal sequences (a and b) should equal 0, was {}",
dist
);
let dist = dict_a.dist(&dict_c);
assert!(
(1. - dist).abs() < EPSILON, "Distance of totally different sequences (a and c) should equal 1, was {}",
dist
);
let dist = dict_a.dist(&dict_d);
assert!(
(0.409_090_909_090_909_06 - dist).abs() < EPSILON, "Distance of a and d should equal 0.40909090909090906, was {}",
dist
);
assert!(
(dict_a.dist(&dict_d) - dict_d.dist(&dict_a)).abs() < EPSILON, "Distance of a and d should be equal to distance of d and a"
);
}
}