diff --git a/src/lib.rs b/src/lib.rs index 7ed58a50..af7d31f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,32 +77,50 @@ pub mod write; /// When compressing data, the compression level can be specified by a value in /// this enum. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Compression(u32); impl Compression { - /// Create a new compression spec with a specific numeric level (0-9). - pub fn new(level: u32) -> Compression { - Compression(level) + /// Create a new compression spec with a specific numeric level in the range `1..=9`. + /// + /// # Panics + /// + /// A level outside of the `1..=9` range will throw a panic. Use [`Self::try_new`] to + /// gracefully handle invalid levels (e.g. from user input). + #[track_caller] + pub const fn new(level: u32) -> Compression { + match Self::try_new(level) { + Some(v) => v, + None => panic!("expected a compression level in the range 1..=9"), + } + } + + /// Create a new compression spec with a specific numeric level in the range `1..=9`. + pub const fn try_new(level: u32) -> Option { + match level { + 1..=9 => Some(Compression(level)), + _ => None, + } } /// Do not compress. + #[deprecated(since = "0.5.1", note = "libbz2 does not support compression level 0")] pub fn none() -> Compression { Compression(0) } /// Optimize for the best speed of encoding. - pub fn fast() -> Compression { + pub const fn fast() -> Compression { Compression(1) } - /// Optimize for the size of data being encoded. - pub fn best() -> Compression { + /// Optimize for smallest output size. + pub const fn best() -> Compression { Compression(9) } /// Return the compression level as an integer. - pub fn level(&self) -> u32 { + pub const fn level(&self) -> u32 { self.0 } } @@ -113,3 +131,30 @@ impl Default for Compression { Compression(6) } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + #[should_panic] + fn new_level_0() { + Compression::new(0); + } + + #[test] + #[should_panic] + fn new_level_10() { + Compression::new(10); + } + + #[test] + fn try_new() { + assert!(Compression::try_new(0).is_none()); + assert!(Compression::try_new(10).is_none()); + + assert_eq!(Compression::try_new(1), Some(Compression::fast())); + assert_eq!(Compression::try_new(6), Some(Compression::default())); + assert_eq!(Compression::try_new(9), Some(Compression::best())); + } +}