Skip to main content

zip/format/
system.rs

1//! Zip System
2
3/// System inside `version made by` (upper byte)
4/// Reference: 4.4.2.2
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
6#[allow(clippy::upper_case_acronyms)]
7#[repr(u8)]
8#[non_exhaustive]
9pub enum System {
10    /// `MS-DOS` and `OS/2` (`FAT` / `VFAT` / `FAT32` file systems; default on Windows)
11    Dos = 0,
12    /// `Amiga`
13    Amiga = 1,
14    /// `OpenVMS`
15    OpenVMS = 2,
16    /// Default on Unix; default for symlinks on all platforms
17    Unix = 3,
18    /// `VM/CMS`
19    VmCms = 4,
20    /// `Atari ST`
21    AtariSt = 5,
22    /// `OS/2 H.P.F.S.`
23    Os2 = 6,
24    /// Legacy `Mac OS`, pre `OS X`
25    Macintosh = 7,
26    /// `Z-System`
27    ZSystem = 8,
28    /// `CP/M`
29    CPM = 9,
30    /// Windows NTFS (with extra attributes; not used by default)
31    WindowsNTFS = 10,
32    /// `MVS (OS/390 - Z/OS)`
33    MVS = 11,
34    /// `VSE`
35    VSE = 12,
36    /// `Acorn Risc`
37    AcornRisc = 13,
38    /// `VFAT`
39    VFAT = 14,
40    /// alternate MVS
41    AlternateMVS = 15,
42    /// `BeOS`
43    BeOS = 16,
44    /// `Tandem`
45    Tandem = 17,
46    /// `OS/400`
47    Os400 = 18,
48    /// `OS X` (Darwin) (with extra attributes; not used by default)
49    OsDarwin = 19,
50    /// unused
51    #[default]
52    Unknown = 255,
53}
54
55impl System {
56    /// Parse `version_made_by` block in local entry block.
57    #[must_use]
58    pub fn from_version_made_by(version_made_by: u16) -> Self {
59        // Extract upper byte from little-endian representation
60        let upper_byte = version_made_by.to_le_bytes()[1];
61        System::from(upper_byte) // from u8
62    }
63
64    /// Extract the system and version from a `version_made_by` field.
65    /// The first byte (lower) is the version, and the second byte (upper) is the system.
66    pub(crate) fn extract_bytes(version_made_by: u16) -> (u8, Self) {
67        let bytes = version_made_by.to_le_bytes();
68        (bytes[0], Self::from(bytes[1]))
69    }
70}
71
72impl From<u8> for System {
73    fn from(system: u8) -> Self {
74        match system {
75            0 => System::Dos,
76            1 => System::Amiga,
77            2 => System::OpenVMS,
78            3 => System::Unix,
79            4 => System::VmCms,
80            5 => System::AtariSt,
81            6 => System::Os2,
82            7 => System::Macintosh,
83            8 => System::ZSystem,
84            9 => System::CPM,
85            10 => System::WindowsNTFS,
86            11 => System::MVS,
87            12 => System::VSE,
88            13 => System::AcornRisc,
89            14 => System::VFAT,
90            15 => System::AlternateMVS,
91            16 => System::BeOS,
92            17 => System::Tandem,
93            18 => System::Os400,
94            19 => System::OsDarwin,
95            _ => System::Unknown,
96        }
97    }
98}
99
100impl From<System> for u8 {
101    fn from(system: System) -> Self {
102        system as u8
103    }
104}
105
106#[cfg(test)]
107mod tests {
108    #[test]
109    fn system() {
110        use super::System;
111        assert_eq!(u8::from(System::Dos), 0u8);
112        assert_eq!(System::Dos as u8, 0u8);
113        assert_eq!(System::Unix as u8, 3u8);
114        assert_eq!(u8::from(System::Unix), 3u8);
115        assert_eq!(System::from(0), System::Dos);
116        assert_eq!(System::from(3), System::Unix);
117        assert_eq!(u8::from(System::Unknown), 255u8);
118        assert_eq!(System::Unknown as u8, 255u8);
119    }
120}