Skip to main content

Crate whichdisk

Crate whichdisk 

Source
Expand description

whichdisk

Cross-platform disk/volume resolver — given a path, tells you which disk it’s on, its mount point, and the relative path

github LoC Build codecov

docs.rs crates.io crates.io license

§Installation

§As a library

[dependencies]
whichdisk = "0.3"

§As a CLI tool

cargo install whichdisk --features cli

§CLI Usage

§Resolve a path

# Resolve the current working directory
whichdisk

# Resolve a specific path
whichdisk -p /home/user/documents

# Output as JSON
whichdisk -o json

# Output as YAML
whichdisk -o yaml

# Combine options
whichdisk -p /tmp -o json

Default output:

device="/dev/disk3s5"
mount_point="/System/Volumes/Data"
relative_path="Users/user/Develop/personal/whichdisk"

JSON output (-o json):

{
  "device": "/dev/disk3s5",
  "mount_point": "/System/Volumes/Data",
  "relative_path": "Users/user/Develop/personal/whichdisk"
}

§List mounted volumes

# List all mounted volumes
whichdisk list

# Shorthand
whichdisk l

# Skip ejectable/removable volumes (show only internal disks)
whichdisk list --skip-ejectable

# Skip non-ejectable volumes (show only removable disks)
whichdisk list --skip-non-ejectable

# Output as JSON
whichdisk list -o json

# Output as YAML
whichdisk list -o yaml

Default output:

mount_point="/" device="/dev/disk3s1s1"

JSON output (list -o json):

[
  {
    "device": "/dev/disk3s1s1",
    "mount_point": "/",
    "is_ejectable": false
  }
]

§Library Usage

§Resolve a path to its disk

use whichdisk::resolve;

fn main() -> std::io::Result<()> {
    let info = resolve("/home/user/documents/report.pdf")?;

    println!("Mount point:    {}", info.mount_point().display());
    println!("Device:         {:?}", info.device());
    println!("Relative path:  {}", info.relative_path().display());
    println!("Ejectable:      {}", info.is_ejectable());

    Ok(())
}

§Get the root filesystem

use whichdisk::root;

fn main() -> std::io::Result<()> {
    let info = root()?;
    println!("Root mount:  {}", info.mount_point().display());
    println!("Root device: {:?}", info.device());
    Ok(())
}

§List mounted volumes

use whichdisk::{list, list_with, list_ejectable, list_non_ejectable, ListOptions};

fn main() -> std::io::Result<()> {
    // List all real (non-virtual) volumes
    for m in list()? {
        println!("{:?} -> {:?} (ejectable: {})",
            m.device(), m.mount_point(), m.is_ejectable());
    }

    // List only ejectable/removable volumes
    for m in list_ejectable()? {
        println!("Removable: {:?}", m.mount_point());
    }

    // List only non-ejectable volumes
    for m in list_non_ejectable()? {
        println!("Internal: {:?}", m.mount_point());
    }

    // Using ListOptions
    let opts = ListOptions::all().set_ejectable_only(true);
    let removable = list_with(opts)?;

    Ok(())
}

§Supported Platforms

PlatformResolve backendList backendEjectable detection
macOS, iOS, watchOS, tvOS, visionOSstatfs via rustixNSFileManager via objc2-foundationNSURLVolumeIsEjectableKey / NSURLVolumeIsRemovableKey
FreeBSD, OpenBSD, DragonFlyBSDstatfs via rustixgetmntinfo via libc/dev/da* or /dev/cd* device prefix
NetBSDstatvfs via libcgetmntinfo via libc/dev/sd* or /dev/cd* device prefix
Linux/proc/self/mountinfo parsing/proc/self/mountinfo parsing/dev/disk/by-id/usb-*
WindowsGetVolumePathNameW via windows-sysFindFirstVolumeW / FindNextVolumeWGetDriveTypeW = DRIVE_REMOVABLE

§Performance

  • Thread-local cache — repeated lookups for paths on the same device skip the underlying syscall/file read entirely
  • Small-buffer optimization — mount points and device names (typically < 56 bytes) are stored inline on the stack; longer values use reference-counted bytes::Bytes (clone is a pointer copy)
  • SIMD-accelerated scanning — uses memchr for null-terminator and newline searches in the BSD statfs buffers and Linux mountinfo parsing

§MSRV

The minimum supported Rust version is 1.85.

§License

whichdisk is under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE, LICENSE-MIT for details.

Copyright (c) 2026 Al Liu.

Structs§

ListOptions
Options for listing mounted volumes.
MountPoint
Information about a mount point (device, path, and whether it’s ejectable).
PathLocation
Information about the disk/volume a specific file path resides on.

Functions§

list
Lists all real (non-virtual) mounted volumes.
list_ejectable
Lists only ejectable/removable mounted volumes.
list_non_ejectable
Lists only non-ejectable/non-removable mounted volumes (internal drives, etc.).
list_with
Lists mounted volumes with the given options.
resolve
Given a path, resolves which disk/volume it resides on.
rootmacOS or iOS or watchOS or tvOS or visionOS or FreeBSD or OpenBSD or DragonFly BSD or NetBSD or Linux or Windows
Returns the PathLocation of the system drive root.