noodles_bgzf/writer/
compression_level.rs

1use std::{error, fmt};
2
3const MIN: u8 = 0;
4
5#[cfg(feature = "libdeflate")]
6const MAX: u8 = 12;
7#[cfg(not(feature = "libdeflate"))]
8const MAX: u8 = 9;
9
10/// A DEFLATE compression level.
11#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
12pub struct CompressionLevel(u8);
13
14impl CompressionLevel {
15    /// No compression.
16    pub const NONE: Self = Self(0);
17
18    /// A compression level optimized for speed.
19    pub const FAST: Self = Self(1);
20
21    /// A compression level optimized for compression rate.
22    pub const BEST: Self = Self(MAX);
23
24    /// Creates a compression level.
25    ///
26    /// # Examples
27    ///
28    /// ```
29    /// use noodles_bgzf::writer::CompressionLevel;
30    /// assert_eq!(CompressionLevel::new(0), Some(CompressionLevel::NONE));
31    /// assert!(CompressionLevel::new(255).is_none());
32    /// ```
33    pub const fn new(n: u8) -> Option<Self> {
34        if n <= MAX {
35            Some(Self(n))
36        } else {
37            None
38        }
39    }
40
41    /// Returns the inner value.
42    ///
43    /// # Examples
44    ///
45    /// ```
46    /// use noodles_bgzf::writer::CompressionLevel;
47    /// assert_eq!(CompressionLevel::NONE.get(), 0);
48    /// ```
49    pub const fn get(&self) -> u8 {
50        self.0
51    }
52
53    /// Returns a compression level to disable compression.
54    ///
55    /// # Examples
56    ///
57    /// ```
58    /// use noodles_bgzf::writer::CompressionLevel;
59    /// let compression_level = CompressionLevel::none();
60    /// ```
61    #[deprecated(since = "0.29.0", note = "Use `CompressionLevel::NONE` instead.")]
62    pub fn none() -> Self {
63        Self(0)
64    }
65
66    /// Returns a compression level optimized for speed.
67    ///
68    /// # Examples
69    ///
70    /// ```
71    /// use noodles_bgzf::writer::CompressionLevel;
72    /// let compression_level = CompressionLevel::fast();
73    /// ```
74    #[deprecated(since = "0.29.0", note = "Use `CompressionLevel::FAST` instead.")]
75    pub fn fast() -> Self {
76        Self(1)
77    }
78
79    /// Returns a compression level optimized for compression rate.
80    ///
81    /// # Examples
82    ///
83    /// ```
84    /// use noodles_bgzf::writer::CompressionLevel;
85    /// let compression_level = CompressionLevel::best();
86    /// ```
87    #[deprecated(since = "0.29.0", note = "Use `CompressionLevel::BEST` instead.")]
88    pub fn best() -> Self {
89        Self(MAX)
90    }
91}
92
93impl Default for CompressionLevel {
94    fn default() -> Self {
95        Self(6)
96    }
97}
98
99/// An error returned when a raw DEFLATE compression level fails to convert.
100#[derive(Clone, Debug, Eq, PartialEq)]
101pub enum TryFromU8Error {
102    Invalid(u8),
103}
104
105impl error::Error for TryFromU8Error {}
106
107impl fmt::Display for TryFromU8Error {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        match self {
110            Self::Invalid(n) => write!(f, "invalid input: {n}"),
111        }
112    }
113}
114
115impl TryFrom<u8> for CompressionLevel {
116    type Error = TryFromU8Error;
117
118    fn try_from(n: u8) -> Result<Self, Self::Error> {
119        match n {
120            MIN..=MAX => Ok(Self(n)),
121            _ => Err(TryFromU8Error::Invalid(n)),
122        }
123    }
124}
125
126impl From<CompressionLevel> for u8 {
127    fn from(compression_level: CompressionLevel) -> Self {
128        compression_level.0
129    }
130}
131
132#[cfg(feature = "libdeflate")]
133impl From<CompressionLevel> for libdeflater::CompressionLvl {
134    fn from(compression_level: CompressionLevel) -> Self {
135        // SAFETY: The raw value is guaranteed to be between MIN and MAX, inclusive.
136        Self::new(i32::from(u8::from(compression_level))).unwrap()
137    }
138}
139
140#[cfg(not(feature = "libdeflate"))]
141impl From<CompressionLevel> for flate2::Compression {
142    fn from(compression_level: CompressionLevel) -> Self {
143        Self::new(u32::from(u8::from(compression_level)))
144    }
145}
146
147#[allow(deprecated)]
148#[cfg(test)]
149mod tests {
150    use super::*;
151
152    #[test]
153    fn test_none() {
154        assert_eq!(CompressionLevel::none(), CompressionLevel(0));
155    }
156
157    #[test]
158    fn test_fast() {
159        assert_eq!(CompressionLevel::fast(), CompressionLevel(1));
160    }
161
162    #[test]
163    fn test_best() {
164        assert_eq!(CompressionLevel::best(), CompressionLevel(MAX));
165    }
166
167    #[test]
168    fn test_default() {
169        assert_eq!(CompressionLevel::default(), CompressionLevel(6));
170    }
171}