pub struct WorkspaceRoots { /* private fields */ }Expand description
The canonical workspace roots plus the lexical aliases they may be named by.
A path is admitted by WorkspaceRoots::validate only if it passes the
lexical pre-check against the canonical roots and their aliases (configured
form, logical $PWD) and its physical, canonical form lies under a
canonical root; the aliases only widen the pre-check.
Cheap to clone (both lists are shared). Fields are private so every instance upholds the invariants: aliases are absolute, simplified, lexically normalized and distinct from the canonical roots.
Implementations§
Source§impl WorkspaceRoots
impl WorkspaceRoots
Sourcepub fn from_configured(roots: &[ConfiguredRoot]) -> Result<Self, Error>
pub fn from_configured(roots: &[ConfiguredRoot]) -> Result<Self, Error>
Builds the root set for the workspace.roots of a configuration.
Relative roots are resolved against the process working directory and
must exist; an empty list means the working directory itself. Absolute
roots that cannot be canonicalized (for example a directory created
after startup) fall back to their longest existing prefix. The
configured spelling, the working-directory spelling and the logical
$PWD spelling are kept as aliases, but only when they verifiably
resolve to the same root, so a client naming a root the way it was
configured (for example a /var temp dir that canonicalizes to
/private/var) is still admitted.
The working directory is read only when a root needs it, so a fully-absolute list does not fail startup over an unreadable cwd.
§Errors
Returns Error::Config for a relative root that cannot be
canonicalized and Error::Io when the working directory is needed
but unreadable.
§Examples
use mcpls_core::bridge::WorkspaceRoots;
use mcpls_core::config::ConfiguredRoot;
let roots = WorkspaceRoots::from_configured(&[ConfiguredRoot::new(std::env::temp_dir())?])?;
assert!(!roots.is_empty());Sourcepub async fn validate(&self, path: &ClientPath) -> Result<WorkspacePath, Error>
pub async fn validate(&self, path: &ClientPath) -> Result<WorkspacePath, Error>
Validates a client path against the roots, canonicalizing it on the blocking pool so a slow filesystem cannot stall a runtime worker.
See Self::validate_blocking for the checks and errors.
§Errors
As Self::validate_blocking, plus Error::TaskFailed when the
blocking task panics.
Sourcepub fn validate_blocking(
&self,
path: &ClientPath,
) -> Result<WorkspacePath, Error>
pub fn validate_blocking( &self, path: &ClientPath, ) -> Result<WorkspacePath, Error>
Validates a client path against the roots on the calling thread.
The lexical check (absolute, ./.. resolved, against the canonical
roots and their aliases) is only a pre-filter: it rejects an
out-of-workspace path without touching the filesystem and can only
reject, never accept. The decision that counts uses the physical
path: the original path is canonicalized (so .. after a symlink is
resolved against the real directory) and that canonical form must lie
under a canonical root. The returned path is the canonical one.
Touches the filesystem; async callers use Self::validate.
§Errors
Returns Error::NoWorkspaceRoots if no root is configured – fails
closed rather than allowing unrestricted access – and
Error::PathOutsideWorkspace if the path is outside every root.
When the lexical check admitted the path but it cannot be
canonicalized, Error::FileIo is returned (for example it does not
exist), or Error::MalformedPath when the path itself is malformed
(it runs through a regular file, or has an invalid or over-long name).