Skip to main content

WorkspacePathResolver

Struct WorkspacePathResolver 

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

Workspace path resolver

Normalizes and validates paths relative to a workspace root. This is the only way to create WorkspaceFilePath instances.

§Responsibilities

  • Convert any path (absolute/relative) to WorkspaceFilePath
  • Normalize paths (resolve .. and .)
  • Validate paths are within workspace
  • Share workspace_root via Arc<Path> for efficient cloning

§Example

let resolver = WorkspacePathResolver::new("/home/user/project".into());

// Absolute path
let p1 = resolver.resolve("/home/user/project/src/lib.rs")?;

// Relative path (resolved from CWD)
let p2 = resolver.resolve("./src/../src/lib.rs")?;

// Strict mode (also checks file existence)
let p3 = resolver.resolve_strict("src/lib.rs")?;

Implementations§

Source§

impl WorkspacePathResolver

Source

pub fn new(workspace_root: PathBuf) -> Self

Create a new resolver with the given workspace root

Defaults to WorkspaceType::Workspace. Use with_type for explicit control.

Source

pub fn with_type(workspace_root: PathBuf, workspace_type: WorkspaceType) -> Self

Create a new resolver with explicit workspace type

Source

pub fn workspace_type(&self) -> WorkspaceType

Get the workspace type

Source

pub fn resolve_with_provider<P: WorkspaceMetadataProvider>( &self, path: impl AsRef<Path>, provider: &P, ) -> Result<WorkspaceFilePath, ResolveError>

Resolve any path to a WorkspaceFilePath with provider-based crate resolution

  • Absolute path → convert to relative from workspace_root
  • Relative path → resolve from CWD, then convert
  • .. / . → resolved
  • Outside workspace → error
  • crate_name → resolved from provider
Source

pub fn resolve_strict_with_provider<P: WorkspaceMetadataProvider>( &self, path: impl AsRef<Path>, provider: &P, ) -> Result<WorkspaceFilePath, ResolveError>

Resolve with file existence check (strict mode)

Source

pub fn resolve_relative_with_crate( &self, relative: impl AsRef<Path>, crate_name: CrateName, ) -> WorkspaceFilePath

Resolve from a path that’s already relative to workspace root (with explicit crate name)

This skips CWD resolution and directly creates a WorkspaceFilePath. Useful when you already have a known-good relative path and crate name.

Source

pub fn resolve_relative_with_provider<P: WorkspaceMetadataProvider>( &self, relative: impl AsRef<Path>, provider: &P, ) -> Option<WorkspaceFilePath>

Resolve from a path that’s already relative to workspace root (with provider)

This skips CWD resolution and uses the provider to resolve the crate name.

Source

pub fn workspace_root(&self) -> &Path

Get the workspace root

Source

pub fn workspace_root_arc(&self) -> Arc<Path>

Get the workspace root as Arc (for deserialization)

Source

pub fn module_to_file( &self, module_path: &SymbolPath, crate_name: &CrateName, span_file: Option<&WorkspaceFilePath>, ) -> WorkspaceFilePath

Resolve module path to file path

This method centralizes the logic for determining which file a module belongs to. It handles the distinction between:

  • Crate root (depth 1): span points to the actual file (main.rs/lib.rs)
  • Sub-modules (depth > 1): span points to declaration site (mod foo; in lib.rs), so path-based inference is needed to get the actual file (foo.rs)
§Arguments
  • module_path: The symbol path of the module
  • crate_name: The crate name for path inference
  • span_file: Optional span file (use for crate root to preserve main.rs vs lib.rs)
§Example
let resolver = WorkspacePathResolver::new("/workspace".into());

// For crate root with span → uses span file (preserves main.rs)
let file = resolver.module_to_file(&module_path, &crate_name, Some(&span_file));

// For sub-module → uses path-based inference
let file = resolver.module_to_file(&module_path, &crate_name, None);
Source

pub fn resolve( &self, path: impl AsRef<Path>, ) -> Result<WorkspaceFilePath, ResolveError>

Resolve any path to a WorkspaceFilePath (infers crate_name from path)

This is a simplified API that attempts to infer the crate name from the path. It looks for crates/<crate-name>/ in the path structure.

For more control, use resolve_with_provider or resolve_relative_with_crate.

Source

pub fn resolve_relative( &self, relative: impl AsRef<Path>, ) -> Option<WorkspaceFilePath>

Resolve from a path that’s already relative to workspace root (infers crate_name)

This is a simplified API that skips CWD resolution and infers the crate name.

Source

pub fn validate_crate_path( &self, path: &str, workspace_members: &[String], ) -> Result<(), ResolveError>

Validate that a crate:: prefixed path is unambiguous in this workspace

In a multi-crate workspace (WorkspaceType::Workspace), paths starting with crate:: are ambiguous because it’s unclear which crate is being referred to.

§Arguments
  • path: The path string to validate (e.g., “crate::domain::model”)
  • workspace_members: List of workspace member paths for error message (e.g., [“crates/core”, “crates/api”])
§Returns
  • Ok(()) if the path is unambiguous (single crate or doesn’t start with crate::)
  • Err(ResolveError::AmbiguousCratePath) if ambiguous in multi-crate workspace
§Example
let resolver = WorkspacePathResolver::with_type(root, WorkspaceType::Workspace);
let members = vec!["crates/core".to_string(), "crates/api".to_string()];

// This will error in multi-crate workspace
resolver.validate_crate_path("crate::domain", &members)?;

// These are OK
resolver.validate_crate_path("core::domain", &members)?;  // explicit crate name
resolver.validate_crate_path("src/domain.rs", &members)?; // file path

Trait Implementations§

Source§

impl Clone for WorkspacePathResolver

Source§

fn clone(&self) -> WorkspacePathResolver

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for WorkspacePathResolver

Source§

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

Formats the value using the given formatter. Read more

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.