Skip to main content

LogicalPathContext

Struct LogicalPathContext 

Source
pub struct LogicalPathContext { /* private fields */ }
Expand description

A context that holds zero or one active prefix mappings between canonical (symlink-resolved) and logical (symlink-preserving) paths.

Created via LogicalPathContext::detect(). Immutable after construction.

§Thread Safety

LogicalPathContext is Send + Sync — it can be shared across threads.

§Platform Behavior

  • Linux/macOS: Reads $PWD and compares against getcwd() to detect symlink prefix mappings.
  • Windows: Compares current_dir() (preserves junctions, subst drives, mapped drives) against canonicalize() (resolves to physical path) to detect NTFS junction, directory symlink, subst drive, and mapped drive mappings. The \\?\ prefix is stripped before comparison.

Implementations§

Source§

impl LogicalPathContext

Source

pub fn detect() -> LogicalPathContext

Detect the active prefix mapping by comparing logical and canonical current working directory paths.

  • Unix: Compares $PWD (logical) against getcwd() (canonical).
  • Windows: Compares current_dir() (logical, preserves junctions/subst) against canonicalize(current_dir()) (canonical, physical path) with \\?\ prefix stripped.

Returns a context with no active mapping (all translations become no-ops) when:

  • $PWD is unset (Unix)
  • The logical and canonical CWD are identical (no indirection in effect)
  • $PWD is stale (Unix: points to a non-existent directory)
  • The current directory cannot be determined

This function is infallible — detection failures are handled by returning a no-op context.

§Panics

This function never panics.

§Examples
use logical_path::LogicalPathContext;

let ctx = LogicalPathContext::detect();
if ctx.has_mapping() {
    println!("Path mapping detected");
}
Source

pub fn has_mapping(&self) -> bool

Returns true if an active prefix mapping was detected.

When this returns false, to_logical() and to_canonical() will always return their input unchanged.

§Examples
use logical_path::LogicalPathContext;

let ctx = LogicalPathContext::detect();
if ctx.has_mapping() {
    println!("Will translate paths");
} else {
    println!("No path mapping detected — paths returned unchanged");
}
Source

pub fn to_logical(&self, path: &Path) -> PathBuf

Translate a canonical (symlink-resolved) path to its logical (symlink-preserving) equivalent.

If the context has an active mapping and the path starts with the canonical prefix, the canonical prefix is replaced with the logical prefix. The translation is validated via round-trip canonicalization before being returned.

Returns the input path unchanged when:

  • No active mapping exists
  • The path does not start with the canonical prefix
  • The path is relative (not absolute)
  • Round-trip validation fails
  • Canonicalization of the translated path fails (e.g., path doesn’t exist on disk)
§Panics

This function never panics, even with non-UTF-8 path components.

§Examples
use logical_path::LogicalPathContext;
use std::path::Path;

let ctx = LogicalPathContext::detect();
let canonical = Path::new("/mnt/wsl/workspace/project/src/main.rs");
let logical = ctx.to_logical(canonical);
// Display the logical path to the user
println!("{}", logical.display());
Source

pub fn to_canonical(&self, path: &Path) -> PathBuf

Translate a logical (symlink-preserving) path to its canonical (symlink-resolved) equivalent.

If the context has an active mapping and the path starts with the logical prefix, the logical prefix is replaced with the canonical prefix. The translation is validated via round-trip canonicalization before being returned.

Returns the input path unchanged when:

  • No active mapping exists
  • The path does not start with the logical prefix
  • The path is relative (not absolute)
  • Round-trip validation fails
  • Canonicalization of the translated path fails (e.g., path doesn’t exist on disk)
§Panics

This function never panics, even with non-UTF-8 path components.

§Examples
use logical_path::LogicalPathContext;
use std::path::Path;

let ctx = LogicalPathContext::detect();
let logical = Path::new("/workspace/project/src/main.rs");
let canonical = ctx.to_canonical(logical);
// Use the canonical path for filesystem operations
if canonical.exists() {
    println!("File exists at {}", canonical.display());
}

Trait Implementations§

Source§

impl Clone for LogicalPathContext

Source§

fn clone(&self) -> LogicalPathContext

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LogicalPathContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for LogicalPathContext

Source§

fn default() -> Self

Returns a context with no active mapping.

Equivalent to calling detect() in an environment with no path indirections or mappings in effect. All translations return their input unchanged.

Source§

impl PartialEq for LogicalPathContext

Source§

fn eq(&self, other: &LogicalPathContext) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for LogicalPathContext

Source§

impl StructuralPartialEq for LogicalPathContext

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.