Skip to main content

use_zstd/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4//! Zstd labels and option metadata for `RustUse`.
5
6/// Common zstd file extension.
7pub const ZSTD_EXTENSION: &str = "zst";
8/// Common zstd-compressed tar extension.
9pub const TAR_ZSTD_EXTENSION: &str = "tar.zst";
10/// Common Zstandard label.
11pub const ZSTD_LABEL: &str = "zstd";
12/// Common zstd-related extensions.
13pub const ZSTD_EXTENSIONS: &[&str] = &["zst", "zstd", "tzst", "tar.zst", "tar.zstd"];
14
15/// Zstd frame shape labels.
16#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
17pub enum ZstdFrameKind {
18    /// Standard zstd frame.
19    #[default]
20    Standard,
21    /// Single segment zstd frame.
22    SingleSegment,
23    /// Skippable zstd frame.
24    Skippable,
25    /// Unknown or intentionally unspecified frame kind.
26    Unknown,
27}
28
29impl ZstdFrameKind {
30    /// Returns a stable lowercase label.
31    #[must_use]
32    pub const fn as_str(self) -> &'static str {
33        match self {
34            Self::Standard => "standard",
35            Self::SingleSegment => "single-segment",
36            Self::Skippable => "skippable",
37            Self::Unknown => "unknown",
38        }
39    }
40}
41
42/// Zstd option metadata.
43#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
44pub struct ZstdOptions {
45    /// Numeric zstd compression level, when specified by the caller.
46    pub level: Option<i32>,
47    /// Whether a checksum should be described as present.
48    pub checksum: bool,
49    /// Optional dictionary identifier.
50    pub dictionary_id: Option<u32>,
51    /// Frame shape label.
52    pub frame_kind: ZstdFrameKind,
53}
54
55impl ZstdOptions {
56    /// Creates default zstd option metadata.
57    #[must_use]
58    pub const fn new() -> Self {
59        Self {
60            level: None,
61            checksum: false,
62            dictionary_id: None,
63            frame_kind: ZstdFrameKind::Standard,
64        }
65    }
66
67    /// Adds a numeric compression level label.
68    #[must_use]
69    pub const fn with_level(mut self, level: i32) -> Self {
70        self.level = Some(level);
71        self
72    }
73
74    /// Sets whether checksum metadata is present.
75    #[must_use]
76    pub const fn with_checksum(mut self, checksum: bool) -> Self {
77        self.checksum = checksum;
78        self
79    }
80
81    /// Adds a dictionary identifier.
82    #[must_use]
83    pub const fn with_dictionary_id(mut self, dictionary_id: u32) -> Self {
84        self.dictionary_id = Some(dictionary_id);
85        self
86    }
87
88    /// Sets the frame shape label.
89    #[must_use]
90    pub const fn with_frame_kind(mut self, frame_kind: ZstdFrameKind) -> Self {
91        self.frame_kind = frame_kind;
92        self
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::{TAR_ZSTD_EXTENSION, ZSTD_EXTENSIONS, ZstdFrameKind, ZstdOptions};
99
100    #[test]
101    fn exposes_zstd_labels() {
102        assert_eq!(TAR_ZSTD_EXTENSION, "tar.zst");
103        assert!(ZSTD_EXTENSIONS.contains(&"tar.zstd"));
104    }
105
106    #[test]
107    fn stores_option_metadata() {
108        let options = ZstdOptions::new()
109            .with_level(3)
110            .with_checksum(true)
111            .with_dictionary_id(42)
112            .with_frame_kind(ZstdFrameKind::SingleSegment);
113
114        assert_eq!(options.level, Some(3));
115        assert!(options.checksum);
116        assert_eq!(options.dictionary_id, Some(42));
117        assert_eq!(options.frame_kind.as_str(), "single-segment");
118    }
119}