compress_lib/level.rs
1//! Compression levels.
2
3use crate::{Error, ErrorKind};
4
5/// A compression level, 0 to 9, with zlib's meaning: 0 stores without
6/// compressing, 1 is the fastest, 9 compresses best, 6 is the default.
7///
8/// # Examples
9///
10/// ```
11/// use compress_lib::Level;
12///
13/// assert_eq!(Level::DEFAULT.get(), 6);
14/// assert_eq!(Level::new(9)?, Level::BEST);
15/// assert!(Level::new(10).is_err());
16/// # Ok::<(), compress_lib::Error>(())
17/// ```
18#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct Level(u8);
20
21impl Level {
22 /// Level 0: stored blocks, no compression.
23 pub const NONE: Level = Level(0);
24 /// Level 1: the fastest.
25 pub const FAST: Level = Level(1);
26 /// Level 6: the default balance of speed and size.
27 pub const DEFAULT: Level = Level(6);
28 /// Level 9: the smallest output.
29 pub const BEST: Level = Level(9);
30
31 /// The level `n`, or `InvalidLevel` above 9.
32 ///
33 /// # Errors
34 ///
35 /// [`ErrorKind::InvalidLevel`] when `n > 9`.
36 ///
37 /// # Examples
38 ///
39 /// ```
40 /// use compress_lib::{ErrorKind, Level};
41 ///
42 /// assert_eq!(Level::new(1)?, Level::FAST);
43 /// assert_eq!(Level::new(12).unwrap_err().kind(), ErrorKind::InvalidLevel);
44 /// # Ok::<(), compress_lib::Error>(())
45 /// ```
46 pub const fn new(n: u8) -> Result<Level, Error> {
47 if n <= 9 {
48 Ok(Level(n))
49 } else {
50 Err(Error::config(ErrorKind::InvalidLevel))
51 }
52 }
53
54 /// The number, 0 to 9.
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// assert_eq!(compress_lib::Level::BEST.get(), 9);
60 /// ```
61 #[must_use]
62 pub const fn get(self) -> u8 {
63 self.0
64 }
65}
66
67impl Default for Level {
68 fn default() -> Self {
69 Self::DEFAULT
70 }
71}
72
73impl TryFrom<u8> for Level {
74 type Error = Error;
75
76 fn try_from(n: u8) -> Result<Self, Error> {
77 Level::new(n)
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_level_every_value_zero_to_nine_valid() {
87 for n in 0..=9 {
88 assert_eq!(Level::new(n).map(Level::get), Ok(n));
89 }
90 }
91
92 #[test]
93 fn test_level_ten_and_above_invalid() {
94 for n in 10..=255u8 {
95 assert_eq!(
96 Level::new(n).map_err(|e| e.kind()),
97 Err(ErrorKind::InvalidLevel)
98 );
99 assert!(Level::try_from(n).is_err());
100 }
101 }
102
103 #[test]
104 fn test_level_constants_and_default() {
105 assert_eq!(Level::NONE.get(), 0);
106 assert_eq!(Level::FAST.get(), 1);
107 assert_eq!(Level::default(), Level::DEFAULT);
108 assert!(Level::FAST < Level::BEST);
109 }
110}