use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::OnceLock;
#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "linux")]
use linux::mounts;
#[cfg(target_os = "macos")]
use macos::mounts;
#[derive(Clone)]
pub struct MountedFs {
pub dest: PathBuf,
pub fstype: String,
pub source: String,
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
#[cfg(target_os = "macos")]
GetFSStatError(i32),
#[cfg(target_os = "linux")]
IOError(std::io::Error),
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
#[allow(unreachable_patterns)]
match self {
#[cfg(target_os = "macos")]
Error::GetFSStatError(err) => write!(f, "getfsstat failed: {err}"),
#[cfg(target_os = "linux")]
Error::IOError(err) => write!(f, "failed to read /proc/mounts: {err}"),
_ => write!(f, "Unknown error"),
}
}
}
pub(super) fn all_mounts() -> &'static HashMap<PathBuf, MountedFs> {
static ALL_MOUNTS: OnceLock<HashMap<PathBuf, MountedFs>> = OnceLock::new();
ALL_MOUNTS.get_or_init(|| {
#[allow(unused_mut)]
let mut mount_map: HashMap<PathBuf, MountedFs> = HashMap::new();
#[cfg(any(target_os = "linux", target_os = "macos"))]
if let Ok(mounts) = mounts() {
for mount in mounts {
mount_map.insert(mount.dest.clone(), mount);
}
}
mount_map
})
}