Skip to main content

which_fs/
magic.rs

1// SPDX-FileCopyrightText: 2026 Manuel Quarneti <mq1@ik.me>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
5
6#![allow(clippy::cast_possible_wrap)]
7
8use crate::FsKind;
9
10#[cfg(target_os = "linux")]
11type Magic = rustix::fs::FsWord;
12
13#[cfg(target_os = "macos")]
14type CharType = i8;
15
16#[cfg(windows)]
17type CharType = u16;
18
19#[cfg(any(target_os = "macos", target_os = "windows"))]
20type Magic = [CharType; 16];
21
22#[cfg(any(target_os = "macos", target_os = "windows"))]
23const fn to_magic<const L: usize>(s: &'static [u8; L]) -> Magic {
24    let mut buf = [0; 16];
25
26    let mut i = 0;
27    while i < L {
28        buf[i] = s[i] as CharType;
29        i += 1;
30    }
31
32    buf
33}
34
35// FAT32
36// =====
37
38#[cfg(target_os = "linux")]
39const FAT32: Magic = 0x4d44;
40
41#[cfg(target_os = "macos")]
42const FAT32: Magic = to_magic(b"msdos");
43
44#[cfg(windows)]
45const FAT32: Magic = to_magic(b"FAT32");
46
47// EXFAT
48// =====
49
50#[cfg(target_os = "linux")]
51const EXFAT: Magic = 0x2011BAB0;
52
53#[cfg(target_os = "macos")]
54const EXFAT: Magic = to_magic(b"exfat");
55
56#[cfg(windows)]
57const EXFAT: Magic = to_magic(b"exFAT");
58
59// APFS
60// ====
61
62#[cfg(target_os = "macos")]
63const APFS: Magic = to_magic(b"apfs");
64
65// HFS+
66// ====
67
68#[cfg(target_os = "macos")]
69const HFS: Magic = to_magic(b"hfs");
70
71// EXT2/3/4
72// ========
73
74#[cfg(target_os = "linux")]
75const EXT2: Magic = 0xef53;
76
77// BTRFS
78// =====
79
80#[cfg(target_os = "linux")]
81const BTRFS: Magic = 0x9123683E;
82
83// F2FS
84// ====
85
86#[cfg(target_os = "linux")]
87const F2FS: Magic = 0xF2F52010;
88
89// BCACHEFS
90// ========
91
92#[cfg(target_os = "linux")]
93const BCACHEFS: Magic = 0xca451a4e;
94
95// XFS
96// ===
97
98#[cfg(target_os = "linux")]
99const XFS: Magic = 0x58465342;
100
101// FUSE
102// ====
103
104#[cfg(target_os = "linux")]
105const FUSE: Magic = 0x65735546;
106
107#[cfg(target_os = "macos")]
108const FUSE: Magic = to_magic(b"fusefs");
109
110// NTFS
111// ====
112
113#[cfg(target_os = "linux")]
114const NTFS: Magic = 0x5346544e;
115
116#[cfg(windows)]
117const NTFS: Magic = to_magic(b"NTFS");
118
119#[cfg(target_os = "macos")]
120const NTFS: Magic = to_magic(b"ntfs");
121
122#[must_use]
123pub fn which_kind(magic: Magic) -> FsKind {
124    match magic {
125        FAT32 => FsKind::Fat32,
126        EXFAT => FsKind::ExFat,
127        NTFS => FsKind::Ntfs,
128
129        #[cfg(unix)]
130        FUSE => FsKind::Fuse,
131
132        #[cfg(target_os = "macos")]
133        APFS => FsKind::Apfs,
134        #[cfg(target_os = "macos")]
135        HFS => FsKind::Hfs,
136
137        #[cfg(target_os = "linux")]
138        EXT2 => FsKind::Ext2,
139        #[cfg(target_os = "linux")]
140        BTRFS => FsKind::Btrfs,
141        #[cfg(target_os = "linux")]
142        F2FS => FsKind::F2fs,
143        #[cfg(target_os = "linux")]
144        BCACHEFS => FsKind::Bcachefs,
145        #[cfg(target_os = "linux")]
146        XFS => FsKind::Xfs,
147
148        _ => FsKind::Unknown,
149    }
150}