Skip to main content

pedant_core/resolution/rust/
package.rs

1//! The package view: one Cargo package declared inside the project root.
2
3use std::path::{Path, PathBuf};
4use std::sync::Arc;
5
6use super::edition::CargoEdition;
7use super::identity::PackageId;
8use super::version::CargoPackageVersion;
9
10/// A Cargo package whose manifest lies beneath the project root.
11///
12/// Workspace members and eligible in-root path dependencies both appear here;
13/// `is_workspace_member` separates them.
14#[derive(Debug)]
15pub struct RustPackage {
16    pub(super) id: PackageId,
17    pub(super) name: Arc<str>,
18    pub(super) version: CargoPackageVersion,
19    pub(super) rust_version: Option<Arc<str>>,
20    pub(super) edition: CargoEdition,
21    pub(super) manifest_path: Arc<str>,
22    pub(super) relative_directory: Arc<str>,
23    pub(super) directory: Box<Path>,
24    pub(super) workspace_member: bool,
25}
26
27impl RustPackage {
28    /// This package's project-scoped identity.
29    pub fn id(&self) -> PackageId {
30        self.id
31    }
32
33    /// The declared `package.name`.
34    pub fn name(&self) -> &str {
35        &self.name
36    }
37
38    /// The validated direct or workspace-inherited version.
39    pub fn version(&self) -> &CargoPackageVersion {
40        &self.version
41    }
42
43    /// The declared or inherited `rust-version`, when the package states one.
44    pub fn rust_version(&self) -> Option<&str> {
45        self.rust_version.as_deref()
46    }
47
48    /// The direct, inherited, or Cargo-defaulted Rust edition.
49    pub fn edition(&self) -> CargoEdition {
50        self.edition
51    }
52
53    /// The repository-relative, `/`-separated manifest path.
54    pub fn manifest_path(&self) -> &str {
55        &self.manifest_path
56    }
57
58    /// The repository-relative package directory; empty for the root package.
59    pub fn relative_directory(&self) -> &str {
60        &self.relative_directory
61    }
62
63    /// The canonical absolute package directory.
64    pub fn directory(&self) -> &Path {
65        &self.directory
66    }
67
68    /// This package's directory beneath a caller-supplied spelling of the root.
69    ///
70    /// Project loading canonicalizes its root, so a consumer that keys caches
71    /// or reports paths by the root it passed in re-bases through this rather
72    /// than through [`Self::directory`].
73    pub fn directory_in(&self, root: &Path) -> PathBuf {
74        match self.relative_directory.is_empty() {
75            true => root.to_path_buf(),
76            false => root.join(&*self.relative_directory),
77        }
78    }
79
80    /// Whether the workspace declares this package as a member.
81    pub fn is_workspace_member(&self) -> bool {
82        self.workspace_member
83    }
84}