simple-path 0.3.6

Simplify Windows UNC path for `fs::canonicalize`
Documentation

CI-badge crate-badge docs-badge

SimplePath

On Windows, fs::canonicalize returns a path prefixed by "\\?\". such as:

\\?\UNC\server\share\dir

The "\\?\" prefix is called the Win32 File Namespaces. It has advantages such as long paths, and is fine for most modern APIs, but some programs can't handle them. PowerShell and cmd.exe are examples of such programs.

The SimplePath simplifies network share UNC paths so that these programs can handle.

C:\dir Z:\x (network)
fs::canonicalize \\?\C:\dir \\?\UNC\server\share\x
SimplePath C:\dir \\server\share\x
SimplePath with map to drive C:\dir Z:\x

Please see the library documentation for more details, and releases for the change history.

Safety

Technically speaking, since the "\\?\" prefix (Win32 File Namespaces) disables all string parsing and sends the following string directly to the file system, simplifying the path is not always guaranteed to be safe or equivalent.

The SimplePath simplifies paths if all the following conditions are met.

  • The path is prefixed by "\\?\UNC\" (not only by "\\?\").
    • Note: other prefixes such as "\\?\C:" are simplified by dunce, which is included by default.
  • The path doesn't have any invalid characters defined by the Naming Conventions.
  • The path is "connected" on the PC. That is, the network share is listed in the File Explorer, or in the list of connections when you run net use from the command line.

The "long paths" (paths longer than 260 characters) are simplified by default. You can disable long paths being simplified by disallow_long.

Examples

When your PC has a network share on the Z: drive, either by the File Explorer or by the command line such as:

net use Z: \\server\share

Then canonicalizing "Z:\dir\file" will be "\\?\UNC\server\share\dir\file". Neither PowerShell nor cmd.exe can handle this path.

let path = r"Z:\dir\file";
let canonicalized = fs::canonicalize(path)?;
println!("{}", canonicalized.display());

Using the SimplePath prints "\\server\share\dir\file" instead.

let path = r"Z:\dir\file";
let canonicalized = SimplePath::default().canonicalize(path)?;
println!("{}", canonicalized.display());

This path works fine for PowerShell and cmd.exe.

Map to Drive

If you prefer network drive names instead of UNC (\\server\share"), enable the map_to_drive option.

The following code prints "Z:\dir\file" instead of "\\server\share\dir\file".

let path = r"Z:\dir\file";
let simple = SimplePath {
    map_to_drive: true,
    ..Default::default()
};
let simplified = simple.canonicalize(path)?;
println!("{}", simplified.display());

Dunce

The SimplePath calls the dunce crate to normalize some other cases, such as: \\?\C:\foo to C:\foo. You can skip the dunce crate simplification by the skip_dunce option.

let simple = SimplePath { skip_dunce: true, ..Default::default() };

Other Platforms

On other platforms than Windows, the SimplePath returns without doing anything.

You can wrap the calls with #[cfg(windows)] if you prefer, though your programs should build and run fine without doing so.