pub trait SugarPath: Sealed {
// Required methods
fn normalize(&self) -> Cow<'_, Path>;
fn absolutize(&self) -> Cow<'_, Path>;
fn try_absolutize(&self) -> Result<Cow<'_, Path>>;
fn absolutize_with(
&self,
cwd: impl AsRef<Path> + Into<PathBuf>,
) -> Cow<'_, Path>;
fn relative(&self, base: impl AsRef<Path>) -> Cow<'_, Path>;
fn try_relative(&self, base: impl AsRef<Path>) -> Result<Cow<'_, Path>>;
fn relative_with(
&self,
base: impl AsRef<Path>,
cwd: impl AsRef<Path> + Into<PathBuf>,
) -> Cow<'_, Path>;
fn to_slash(&self) -> Cow<'_, str>;
fn try_to_slash(&self) -> Option<Cow<'_, str>>;
fn to_slash_lossy(&self) -> Cow<'_, str>;
fn as_path(&self) -> &Path;
}Expand description
Lexical path operations over borrowed standard Rust path and string types.
Import this trait to call its methods on Path and str. PathBuf,
String, and other types that dereference to one of those types use the
methods through normal method lookup; they do not implement SugarPath
themselves.
The trait is sealed because it is an extension-method namespace, not an
abstraction for downstream path types. Generic APIs should accept a
standard bound such as AsRef<Path>, then call SugarPath methods on the
resulting &Path.
Methods returning Cow may borrow from the receiver when its existing
storage already contains the result. They never borrow from a base or
cwd argument.
§Generic code
use std::path::{Path, PathBuf};
use sugar_path::SugarPath;
fn normalized(path: impl AsRef<Path>) -> PathBuf {
path.as_ref().normalize().into_owned()
}
assert_eq!(normalized(PathBuf::from("src").join("..")), PathBuf::from("."));Required Methods§
Sourcefn normalize(&self) -> Cow<'_, Path>
fn normalize(&self) -> Cow<'_, Path>
Lexically normalizes this path in host-native syntax.
This removes . components and redundant separators, resolves ..
against preceding normal components, and prevents a rooted path from
ascending above its root. An empty path normalizes to .. This operation
does not access the filesystem or resolve symlinks; use
std::fs::canonicalize when physical filesystem identity is required.
One trailing separator is preserved when the input has one. The returned
Cow borrows an already-normalized receiver when possible. A canonical
current-directory result may borrow the static . path; other results
that require a new buffer are owned.
§Examples
use std::path::{Path, PathBuf};
use sugar_path::SugarPath;
let input = PathBuf::from("workspace").join("src").join("..").join("dist");
let expected = Path::new("workspace").join("dist");
assert_eq!(&*input.normalize(), expected);§Windows
Non-verbatim separators are written as \, and the input spelling of a
drive letter is preserved. Verbatim paths retain Rust’s native rule that
/ is a literal character rather than a separator. The minimal .\ is
kept or inserted when its absence would reinterpret the first normal
component as a prefix.
Sourcefn absolutize(&self) -> Cow<'_, Path>
fn absolutize(&self) -> Cow<'_, Path>
Resolves this path against the process current directory and normalizes it.
Resolution removes a non-root trailing separator. An absolute input is
normalized without reading or initializing process cwd state. Other
inputs use the process current directory; with the cached_current_dir
feature, ordinary relative inputs use its lazily initialized snapshot.
A clean absolute receiver may be returned borrowed. A result that requires cwd resolution is owned.
Prefer SugarPath::absolutize_with when the base directory is known, so
the call does not depend on process cwd.
§Examples
Absolute inputs do not consult cwd:
use std::path::Path;
use sugar_path::SugarPath;
#[cfg(target_family = "unix")]
assert_eq!(&*"/workspace/src".absolutize(), Path::new("/workspace/src"));
#[cfg(target_family = "windows")]
assert_eq!(&*r"C:\workspace\src".absolutize(), Path::new(r"C:\workspace\src"));§Windows
On Windows, drive-relative inputs such as C:foo use Windows’ remembered
current directory for that drive. This lookup is authoritative and is not
replaced by the crate’s single cached cwd.
§Panics
Panics if required process cwd or Windows drive-cwd state cannot be
resolved. Use SugarPath::try_absolutize to handle the error.
Sourcefn try_absolutize(&self) -> Result<Cow<'_, Path>>
fn try_absolutize(&self) -> Result<Cow<'_, Path>>
Fallible form of SugarPath::absolutize.
Absolute and otherwise cwd-independent inputs succeed without reading process cwd state, so they do not fail merely because ambient cwd is unavailable.
§Errors
Returns the underlying io::Error if required ambient cwd state cannot
be obtained or a Windows drive-relative path cannot be made absolute.
§Examples
use std::path::Path;
use sugar_path::SugarPath;
#[cfg(target_family = "unix")]
assert_eq!(&*"/workspace".try_absolutize().unwrap(), Path::new("/workspace"));
#[cfg(target_family = "windows")]
assert_eq!(&*r"C:\workspace".try_absolutize().unwrap(), Path::new(r"C:\workspace"));Sourcefn absolutize_with(
&self,
cwd: impl AsRef<Path> + Into<PathBuf>,
) -> Cow<'_, Path>
fn absolutize_with( &self, cwd: impl AsRef<Path> + Into<PathBuf>, ) -> Cow<'_, Path>
Resolves this path against an explicit current directory and normalizes it.
This method never reads process cwd state. An absolute receiver ignores
cwd and may be returned borrowed. A relative result that uses cwd is
owned; an owned PathBuf passed as cwd may provide that result buffer.
The returned value never borrows from cwd.
§Examples
use std::path::Path;
use sugar_path::SugarPath;
#[cfg(target_family = "unix")]
assert_eq!("src/lib.rs".absolutize_with("/workspace"), Path::new("/workspace/src/lib.rs"));
#[cfg(target_family = "windows")]
assert_eq!(r"src\lib.rs".absolutize_with(r"C:\workspace"), Path::new(r"C:\workspace\src\lib.rs"));§Windows
On Windows, an ordinary relative path uses cwd, and a root-relative path
uses cwd’s drive or prefix. A drive-relative receiver such as C:foo is
resolved when cwd supplies drive C’s context. If cwd is on another
drive or has a non-disk prefix, the missing drive context is not read from
the environment or invented: the normalized drive-relative receiver is
returned and is not Path::is_absolute.
§Panics
Panics if the non-absolute receiver needs cwd and cwd is not absolute.
An absolute receiver does not inspect or validate cwd.
Sourcefn relative(&self, base: impl AsRef<Path>) -> Cow<'_, Path>
fn relative(&self, base: impl AsRef<Path>) -> Cow<'_, Path>
Returns the lexical path from base to this receiver.
Call this as target.relative(base). Both inputs are resolved as
SugarPath::absolutize would resolve them, except that cwd-independent
inputs avoid reading ambient cwd state. Equal resolved paths return an
empty path, and result spelling never preserves a non-root target trailing
separator.
A result already present in the receiver, commonly a descendant suffix with trailing separators excluded, may be borrowed. Results that must be rebuilt, including upward and differently rooted results, are owned.
§Windows
Drive and path components compare with ASCII case ignored.
Different drive, UNC share, or namespace roots return the normalized
absolute target because a relative path cannot cross those roots. The
normalized target is also returned when its remaining components cannot
be represented by a standalone native relative Path, including a
verbatim component containing literal / or a leading component that
would be reparsed as a Windows prefix. This target is normally absolute
after resolution, but can remain root-relative or drive-relative when the
unknown shared context deliberately cancels.
§Examples
use std::path::Path;
use sugar_path::SugarPath;
assert_eq!(Path::new("workspace/src").relative("workspace"), Path::new("src"));§Panics
Panics if required process cwd or Windows drive-cwd state cannot be
resolved. Use SugarPath::try_relative to handle the error.
Sourcefn try_relative(&self, base: impl AsRef<Path>) -> Result<Cow<'_, Path>>
fn try_relative(&self, base: impl AsRef<Path>) -> Result<Cow<'_, Path>>
Fallible form of SugarPath::relative.
§Errors
Returns the underlying io::Error if either input requires ambient cwd
state that cannot be obtained. Cwd-independent inputs do not produce this
error merely because process cwd is unavailable.
§Examples
use std::path::Path;
use sugar_path::SugarPath;
#[cfg(target_family = "unix")]
{
let relative = Path::new("/workspace/src").try_relative("/workspace").unwrap();
assert_eq!(&*relative, Path::new("src"));
}
#[cfg(target_family = "windows")]
{
let relative = Path::new(r"C:\workspace\src").try_relative(r"C:\workspace").unwrap();
assert_eq!(&*relative, Path::new("src"));
}Sourcefn relative_with(
&self,
base: impl AsRef<Path>,
cwd: impl AsRef<Path> + Into<PathBuf>,
) -> Cow<'_, Path>
fn relative_with( &self, base: impl AsRef<Path>, cwd: impl AsRef<Path> + Into<PathBuf>, ) -> Cow<'_, Path>
Returns the lexical path from base to this receiver using cwd as the
explicit current directory for relative inputs.
This method never reads process cwd state. If the result is independent
of cwd, cwd is neither inspected nor validated. Otherwise cwd resolves
both inputs using SugarPath::absolutize_with. The returned value may
borrow only from this receiver, never from base or cwd.
§Examples
use std::path::Path;
use sugar_path::SugarPath;
#[cfg(target_family = "unix")]
assert_eq!("src/lib.rs".relative_with("/workspace", "/workspace"), Path::new("src/lib.rs"));
#[cfg(target_family = "windows")]
assert_eq!(r"src\lib.rs".relative_with(r"C:\workspace", r"C:\workspace"), Path::new(r"src\lib.rs"));§Windows
On Windows, a single explicit cwd may not contain the remembered cwd for
another drive. Two root-relative inputs cancel their shared unknown drive.
Two drive-relative inputs with the same drive and the same number of
unresolved leading .. components can likewise cancel that shared
unknown context and produce a relative result. In every other unresolved
or differently rooted case, this method returns the normalized target
instead of fabricating a path relation. That fallback can itself remain
drive-relative and is not guaranteed to satisfy Path::is_absolute.
The unrepresentable-component fallback documented by
SugarPath::relative also applies.
§Panics
Panics if the calculation needs cwd and cwd is not absolute.
Sourcefn to_slash(&self) -> Cow<'_, str>
fn to_slash(&self) -> Cow<'_, str>
Converts native separators to /, requiring valid UTF-8.
This operation does not normalize components. It returns a borrowed string when the path is valid UTF-8 and no separator replacement needs a new buffer.
§Examples
use std::path::PathBuf;
use sugar_path::SugarPath;
let path = PathBuf::from("src").join("lib.rs");
assert_eq!(path.to_slash(), "src/lib.rs");§Panics
Panics if this native path is not valid UTF-8. Use
SugarPath::try_to_slash to preserve that failure or
SugarPath::to_slash_lossy to replace invalid encoding.
Sourcefn try_to_slash(&self) -> Option<Cow<'_, str>>
fn try_to_slash(&self) -> Option<Cow<'_, str>>
Converts native separators to /, returning None for invalid UTF-8.
This is the non-panicking counterpart of SugarPath::to_slash. It never
inserts replacement characters: valid UTF-8 yields the slash-separated
string, and invalid native encoding yields None.
§Examples
use std::path::PathBuf;
use sugar_path::SugarPath;
let path = PathBuf::from("src").join("lib.rs");
assert_eq!(path.try_to_slash().as_deref(), Some("src/lib.rs"));Sourcefn to_slash_lossy(&self) -> Cow<'_, str>
fn to_slash_lossy(&self) -> Cow<'_, str>
Converts native separators to /, replacing invalid encoding with the
Unicode replacement character.
Valid UTF-8 follows the same borrowing behavior as
SugarPath::to_slash. Replacement is irreversible: a result containing
U+FFFD may not round-trip to the original native path. Prefer
SugarPath::to_slash when valid UTF-8 is an invariant, and
SugarPath::try_to_slash when the original native path must be preserved.
§Examples
use std::path::PathBuf;
use sugar_path::SugarPath;
let path = PathBuf::from("src").join("lib.rs");
assert_eq!(path.to_slash_lossy(), "src/lib.rs");Sourcefn as_path(&self) -> &Path
fn as_path(&self) -> &Path
Views this value as a standard Path without allocating.
This is primarily useful for str and String receivers. It performs
no normalization, encoding conversion, or filesystem access.
§Examples
use std::path::PathBuf;
use sugar_path::SugarPath;
assert_eq!("src".as_path().join("lib.rs"), PathBuf::from("src").join("lib.rs"));Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".