pub struct ProjectRootId(/* private fields */);Expand description
Stable canonical identity for a project root.
A ProjectRootId is represented by the canonical filesystem path of an
existing project root. Construction uses std::fs::canonicalize, so the
stored path is absolute, has ./../trailing separators collapsed, and has
symlinks resolved.
Git worktrees are first-class roots: this crate does not ask Git for a repository common-dir and does not collapse linked worktrees back to their main checkout. Because a linked worktree has its own checkout directory, the canonical worktree path is a distinct id from the canonical main-checkout path while alternate spellings of either path still converge.
Implementations§
Source§impl ProjectRootId
impl ProjectRootId
Sourcepub fn from_path(path: impl AsRef<Path>) -> Result<Self, IdentityError>
pub fn from_path(path: impl AsRef<Path>) -> Result<Self, IdentityError>
Resolve an existing filesystem path into a canonical project-root id.
Non-existent paths are rejected with IdentityError::NonExistentPath
instead of being logically normalized. That policy avoids silently
aliasing roots whose future meaning could change when missing path
components or symlinks are later created.
That rejection is load-bearing for callers who use it to DETECT a root
that has gone away, so this constructor keeps it. Callers that must still
address a vanished root – ending or inspecting work that was admitted
while the root existed – use Self::from_path_allowing_missing, which
preserves the aliasing guarantee by a narrower means.
Sourcepub fn from_path_allowing_missing(
path: impl AsRef<Path>,
) -> Result<Self, IdentityError>
pub fn from_path_allowing_missing( path: impl AsRef<Path>, ) -> Result<Self, IdentityError>
Resolve a path into a project-root id even when the path no longer exists.
Resolves the longest prefix that still exists and re-appends the rest,
following any symlink encountered on the missing tail. This is the
behaviour of POSIX realpath on a non-existent path; fs::canonicalize
is the outlier in refusing partial resolution, so this matches a
documented reference rather than inventing a rule.
WHY NOT LEXICAL NORMALIZATION: consumers key durable state on the resolved string. On macOS every temporary directory is reached through a symlink, so a lexically-normalized path is a DIFFERENT string from the id minted while the root existed – the caller would address an empty lineage and receive a confident “no such thing” rather than an error. That is one caller, one spelling, and two ids across time.
WHAT THIS DOES NOT PROMISE: if a missing component later reappears as a
symlink pointing elsewhere, the id moves. Self::from_path does not
prevent that either – it declines to answer while the component is
missing and then resolves through the new link exactly as this does, so
the hazard is shared rather than introduced here. The aliasing guarantee
the strict constructor exists for is preserved by refusing to create NEW
durable state under an id resolved this way; callers admit only
operations that read or end something already recorded.
Sourcepub fn into_path_buf(self) -> PathBuf
pub fn into_path_buf(self) -> PathBuf
Consume the identity and return its canonical path representation.
Trait Implementations§
Source§impl AsRef<Path> for ProjectRootId
impl AsRef<Path> for ProjectRootId
Source§impl Clone for ProjectRootId
impl Clone for ProjectRootId
Source§fn clone(&self) -> ProjectRootId
fn clone(&self) -> ProjectRootId
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more