1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::fmt;
7
8pub const TAR_EXTENSION: &str = "tar";
10pub const TAR_GZIP_EXTENSION: &str = "tar.gz";
12pub const TAR_XZ_EXTENSION: &str = "tar.xz";
14pub const TAR_ZSTD_EXTENSION: &str = "tar.zst";
16
17#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
19pub enum TarEntryType {
20 #[default]
22 Regular,
23 Directory,
25 Symlink,
27 Hardlink,
29 BlockDevice,
31 CharacterDevice,
33 Fifo,
35 GlobalExtendedHeader,
37 ExtendedHeader,
39 Unknown,
41}
42
43impl TarEntryType {
44 #[must_use]
46 pub const fn as_str(self) -> &'static str {
47 match self {
48 Self::Regular => "regular",
49 Self::Directory => "directory",
50 Self::Symlink => "symlink",
51 Self::Hardlink => "hardlink",
52 Self::BlockDevice => "block-device",
53 Self::CharacterDevice => "character-device",
54 Self::Fifo => "fifo",
55 Self::GlobalExtendedHeader => "global-extended-header",
56 Self::ExtendedHeader => "extended-header",
57 Self::Unknown => "unknown",
58 }
59 }
60
61 #[must_use]
63 pub const fn from_typeflag(typeflag: u8) -> Self {
64 match typeflag {
65 0 | b'0' => Self::Regular,
66 b'1' => Self::Hardlink,
67 b'2' => Self::Symlink,
68 b'3' => Self::CharacterDevice,
69 b'4' => Self::BlockDevice,
70 b'5' => Self::Directory,
71 b'6' => Self::Fifo,
72 b'g' => Self::GlobalExtendedHeader,
73 b'x' => Self::ExtendedHeader,
74 _ => Self::Unknown,
75 }
76 }
77
78 #[must_use]
80 pub const fn typeflag(self) -> Option<u8> {
81 match self {
82 Self::Regular => Some(b'0'),
83 Self::Hardlink => Some(b'1'),
84 Self::Symlink => Some(b'2'),
85 Self::CharacterDevice => Some(b'3'),
86 Self::BlockDevice => Some(b'4'),
87 Self::Directory => Some(b'5'),
88 Self::Fifo => Some(b'6'),
89 Self::GlobalExtendedHeader => Some(b'g'),
90 Self::ExtendedHeader => Some(b'x'),
91 Self::Unknown => None,
92 }
93 }
94}
95
96impl fmt::Display for TarEntryType {
97 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
98 formatter.write_str(self.as_str())
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::{TAR_EXTENSION, TAR_GZIP_EXTENSION, TarEntryType};
105
106 #[test]
107 fn maps_tar_typeflags() {
108 assert_eq!(TarEntryType::from_typeflag(b'5'), TarEntryType::Directory);
109 assert_eq!(TarEntryType::from_typeflag(b'2'), TarEntryType::Symlink);
110 assert_eq!(TarEntryType::Regular.typeflag(), Some(b'0'));
111 assert_eq!(TarEntryType::Unknown.typeflag(), None);
112 }
113
114 #[test]
115 fn exposes_tar_extension_labels() {
116 assert_eq!(TAR_EXTENSION, "tar");
117 assert_eq!(TAR_GZIP_EXTENSION, "tar.gz");
118 }
119}