Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/project-model/src/manifest_path.rs')
| -rw-r--r-- | crates/project-model/src/manifest_path.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/crates/project-model/src/manifest_path.rs b/crates/project-model/src/manifest_path.rs new file mode 100644 index 0000000000..4910fd3d11 --- /dev/null +++ b/crates/project-model/src/manifest_path.rs @@ -0,0 +1,51 @@ +//! See [`ManifestPath`]. +use std::{ops, path::Path}; + +use paths::{AbsPath, AbsPathBuf}; + +/// More or less [`AbsPathBuf`] with non-None parent. +/// +/// We use it to store path to Cargo.toml, as we frequently use the parent dir +/// as a working directory to spawn various commands, and its nice to not have +/// to `.unwrap()` everywhere. +/// +/// This could have been named `AbsNonRootPathBuf`, as we don't enforce that +/// this stores manifest files in particular, but we only use this for manifests +/// at the moment in practice. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct ManifestPath { + file: AbsPathBuf, +} + +impl TryFrom<AbsPathBuf> for ManifestPath { + type Error = AbsPathBuf; + + fn try_from(file: AbsPathBuf) -> Result<Self, Self::Error> { + if file.parent().is_none() { + Err(file) + } else { + Ok(ManifestPath { file }) + } + } +} + +impl ManifestPath { + // Shadow `parent` from `Deref`. + pub fn parent(&self) -> &AbsPath { + self.file.parent().unwrap() + } +} + +impl ops::Deref for ManifestPath { + type Target = AbsPath; + + fn deref(&self) -> &Self::Target { + &*self.file + } +} + +impl AsRef<Path> for ManifestPath { + fn as_ref(&self) -> &Path { + self.file.as_ref() + } +} |