lz4_compression/
lib.rs

1//! Pure Rust implementation of LZ4 compression.
2//!
3//! A detailed explanation of the algorithm can be found [here](http://ticki.github.io/blog/how-lz4-works/).
4
5// TODO no-std?
6
7pub mod decompress;
8pub mod compress;
9
10pub mod prelude {
11    pub use crate::decompress::decompress;
12    pub use crate::compress::compress;
13}
14
15
16
17#[cfg(test)]
18mod tests {
19    use std::str;
20    use crate::prelude::*;
21
22    /// Test that the compressed string decompresses to the original string.
23    fn inverse(s: &str) {
24        let compressed = compress(s.as_bytes());
25        println!("Compressed '{}' into {:?}", s, compressed);
26        let decompressed = decompress(&compressed).unwrap();
27        println!("Decompressed it into {:?}", str::from_utf8(&decompressed).unwrap());
28        assert_eq!(decompressed, s.as_bytes());
29    }
30
31    #[test]
32    fn shakespear() {
33        inverse("to live or not to live");
34        inverse("Love is a wonderful terrible thing");
35        inverse("There is nothing either good or bad, but thinking makes it so.");
36        inverse("I burn, I pine, I perish.");
37    }
38
39    #[test]
40    fn save_the_pandas() {
41        inverse("To cute to die! Save the red panda!");
42        inverse("You are 60% water. Save 60% of yourself!");
43        inverse("Save water, it doesn't grow on trees.");
44        inverse("The panda bear has an amazing black-and-white fur.");
45        inverse("The average panda eats as much as 9 to 14 kg of bamboo shoots a day.");
46        inverse("The Empress Dowager Bo was buried with a panda skull in her vault");
47    }
48
49    #[test]
50    fn not_compressible() {
51        inverse("as6yhol.;jrew5tyuikbfewedfyjltre22459ba");
52        inverse("jhflkdjshaf9p8u89ybkvjsdbfkhvg4ut08yfrr");
53    }
54
55    #[test]
56    fn short() {
57        inverse("ahhd");
58        inverse("ahd");
59        inverse("x-29");
60        inverse("x");
61        inverse("k");
62        inverse(".");
63        inverse("ajsdh");
64    }
65
66    #[test]
67    fn empty_string() {
68        inverse("");
69    }
70
71    #[test]
72    fn nulls() {
73        inverse("\0\0\0\0\0\0\0\0\0\0\0\0\0");
74    }
75
76    #[test]
77    fn compression_works() {
78        let s = "The Read trait allows for reading bytes from a source. Implementors of the Read trait are called 'readers'. Readers are defined by one required method, read().";
79
80        inverse(s);
81
82        assert!(compress(s.as_bytes()).len() < s.len());
83    }
84
85    #[test]
86    fn big_compression() {
87        let mut s = Vec::with_capacity(80_000000);
88
89        for n in 0..80_000000 {
90            s.push((n as u8).wrapping_mul(0xA).wrapping_add(33) ^ 0xA2);
91        }
92
93        assert_eq!(&decompress(&compress(&s)).unwrap(), &s);
94    }
95}