Skip to main content

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}