1use {
30 std::{
31 env,
32 path::{Path, PathBuf},
33 },
34 crate::Sealed,
35};
36
37#[cfg(unix)]
38#[cfg(feature="libc")]
39use {
40 core::{
41 ffi::CStr,
42 mem,
43 },
44 alloc::ffi::CString,
45 std::{
46 io::Error,
47 os::unix::prelude::OsStrExt,
48 },
49 crate::{FileSystem, Result},
50};
51
52pub trait PathExt: Sealed {
58
59 fn shorten<P>(&self, base: P) -> &Path where P: AsRef<Path>;
63
64 fn shorten_here(&self) -> &Path;
68
69 #[cfg(all(feature="libc", unix))]
71 #[doc(cfg(all(feature="libc", unix)))]
72 fn file_system(&self) -> Result<FileSystem>;
73
74}
75
76macro_rules! impl_path_ext { ($($ty: ty),+$(,)?) => {
77 $(
78 impl Sealed for $ty {}
79
80 impl PathExt for $ty {
81
82 fn shorten<P>(&self, base: P) -> &Path where P: AsRef<Path> {
83 self.strip_prefix(base).unwrap_or(self)
84 }
85
86 fn shorten_here(&self) -> &Path {
87 env::current_dir().map(|d| self.shorten(d)).unwrap_or(self)
88 }
89
90 #[cfg(all(feature="libc", unix))]
91 #[doc(cfg(all(feature="libc", unix)))]
92 fn file_system(&self) -> Result<FileSystem> {
93 file_system(self)
94 }
95
96 }
97 )+
98}}
99
100impl_path_ext!(&Path, PathBuf);
101
102#[cfg(all(feature="libc", unix))]
104#[doc(cfg(all(feature="libc", unix)))]
105fn file_system(path: &Path) -> Result<FileSystem> {
106 match unsafe {
108 let mut statfs = mem::zeroed::<libc::statfs>();
109 match libc::statfs(CString::new(path.as_os_str().as_bytes())?.as_ptr(), &mut statfs) {
110 0 => statfs.f_type,
111 _ => return Err(fmt_err_code("statfs")),
112 }
113 } {
114 libc::ADFS_SUPER_MAGIC => Ok(FileSystem::ADFSSuper),
115 libc::AFFS_SUPER_MAGIC => Ok(FileSystem::AFFSSuper),
116 libc::AFS_SUPER_MAGIC => Ok(FileSystem::AFSSuper),
117 libc::AUTOFS_SUPER_MAGIC => Ok(FileSystem::AutoFSSuper),
118 libc::BPF_FS_MAGIC => Ok(FileSystem::BpfFS),
119 libc::BTRFS_SUPER_MAGIC => Ok(FileSystem::BtrFSSuper),
120 libc::CGROUP_SUPER_MAGIC => Ok(FileSystem::CgroupSuper),
121 libc::CGROUP2_SUPER_MAGIC => Ok(FileSystem::Cgroup2Super),
122 libc::CODA_SUPER_MAGIC => Ok(FileSystem::CodaSuper),
123 libc::CRAMFS_MAGIC => Ok(FileSystem::CramFS),
124 libc::DEBUGFS_MAGIC => Ok(FileSystem::DebugFS),
125 libc::DEVPTS_SUPER_MAGIC => Ok(FileSystem::DevPtsSuper),
126 libc::ECRYPTFS_SUPER_MAGIC => Ok(FileSystem::EcryptFSSuper),
127 libc::EFS_SUPER_MAGIC => Ok(FileSystem::EFSSuper),
128 libc::EXT4_SUPER_MAGIC => Ok(FileSystem::Ext234Super),
129 libc::F2FS_SUPER_MAGIC => Ok(FileSystem::F2FSSuper),
130 libc::FUSE_SUPER_MAGIC => Ok(FileSystem::FuseSuper),
131 libc::FUTEXFS_SUPER_MAGIC => Ok(FileSystem::FutexFSSuper),
132 libc::HOSTFS_SUPER_MAGIC => Ok(FileSystem::HostFSSuper),
133 libc::HPFS_SUPER_MAGIC => Ok(FileSystem::HPFSSuper),
134 libc::HUGETLBFS_MAGIC => Ok(FileSystem::HugeTLBFS),
135 libc::ISOFS_SUPER_MAGIC => Ok(FileSystem::IsoFSSuper),
136 libc::JFFS2_SUPER_MAGIC => Ok(FileSystem::JFFS2Super),
137 libc::MINIX_SUPER_MAGIC => Ok(FileSystem::MINIXSuper),
138 libc::MINIX_SUPER_MAGIC2 => Ok(FileSystem::MINIXSuper2),
139 libc::MINIX2_SUPER_MAGIC => Ok(FileSystem::MINIX2Super),
140 libc::MINIX2_SUPER_MAGIC2 => Ok(FileSystem::MINIX2Super2),
141 libc::MINIX3_SUPER_MAGIC => Ok(FileSystem::MINIX3Super),
142 libc::MSDOS_SUPER_MAGIC => Ok(FileSystem::MSDOSSuper),
143 libc::NCP_SUPER_MAGIC => Ok(FileSystem::NCPSuper),
144 libc::NFS_SUPER_MAGIC => Ok(FileSystem::NFSSuper),
145 libc::NILFS_SUPER_MAGIC => Ok(FileSystem::NILFSSuper),
146 libc::NSFS_MAGIC => Ok(FileSystem::NSFS),
147 libc::OCFS2_SUPER_MAGIC => Ok(FileSystem::OCFS2Super),
148 libc::OPENPROM_SUPER_MAGIC => Ok(FileSystem::OpenPROMSuper),
149 libc::OVERLAYFS_SUPER_MAGIC => Ok(FileSystem::OverlayFSSuper),
150 libc::PROC_SUPER_MAGIC => Ok(FileSystem::ProcSuper),
151 libc::QNX4_SUPER_MAGIC => Ok(FileSystem::QNX4Super),
152 libc::QNX6_SUPER_MAGIC => Ok(FileSystem::QNX6Super),
153 libc::REISERFS_SUPER_MAGIC => Ok(FileSystem::ReiserFSSuper),
154 libc::SECURITYFS_MAGIC => Ok(FileSystem::SecurityFS),
155 libc::SELINUX_MAGIC => Ok(FileSystem::SELinux),
156 libc::SMACK_MAGIC => Ok(FileSystem::Smack),
157 libc::SMB_SUPER_MAGIC => Ok(FileSystem::SMBSuper),
158 libc::SYSFS_MAGIC => Ok(FileSystem::SysFS),
159 libc::TMPFS_MAGIC => Ok(FileSystem::TmpFS),
160 libc::TRACEFS_MAGIC => Ok(FileSystem::TraceFS),
161 libc::UDF_SUPER_MAGIC => Ok(FileSystem::UDFSuper),
162 libc::USBDEVICE_SUPER_MAGIC => Ok(FileSystem::USBDeviceSuper),
163 libc::XENFS_SUPER_MAGIC => Ok(FileSystem::XENFSSuper),
164 libc::XFS_SUPER_MAGIC => Ok(FileSystem::XFSSuper),
165 _ => Ok(FileSystem::Unknown),
166 }
167}
168
169#[cfg(feature="libc")]
170#[doc(cfg(feature="libc"))]
171fn fmt_err_code<S>(fn_name: S) -> Error where S: AsRef<str> {
172 let err_code = unsafe {
173 *libc::__errno_location()
174 };
175 err!(
176 "libc::{fn_name}() failed: {err_code}: {err:?}",
177 fn_name=fn_name.as_ref(),
178 err=unsafe { CStr::from_ptr(libc::strerror(err_code)) },
179 )
180}