project_model/
manifest_path.rs

1//! See [`ManifestPath`].
2use std::{borrow::Borrow, fmt, ops};
3
4use paths::{AbsPath, AbsPathBuf, Utf8Path};
5
6/// More or less [`AbsPathBuf`] with non-None parent.
7///
8/// We use it to store path to Cargo.toml, as we frequently use the parent dir
9/// as a working directory to spawn various commands, and its nice to not have
10/// to `.unwrap()` everywhere.
11///
12/// This could have been named `AbsNonRootPathBuf`, as we don't enforce that
13/// this stores manifest files in particular, but we only use this for manifests
14/// at the moment in practice.
15#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
16pub struct ManifestPath {
17    file: AbsPathBuf,
18}
19
20impl TryFrom<AbsPathBuf> for ManifestPath {
21    type Error = AbsPathBuf;
22
23    fn try_from(file: AbsPathBuf) -> Result<Self, Self::Error> {
24        if file.parent().is_none() { Err(file) } else { Ok(ManifestPath { file }) }
25    }
26}
27
28impl From<ManifestPath> for AbsPathBuf {
29    fn from(it: ManifestPath) -> Self {
30        it.file
31    }
32}
33
34impl ManifestPath {
35    // Shadow `parent` from `Deref`.
36    pub fn parent(&self) -> &AbsPath {
37        self.file.parent().unwrap()
38    }
39
40    pub fn canonicalize(&self) -> ! {
41        (**self).canonicalize()
42    }
43
44    pub fn is_rust_manifest(&self) -> bool {
45        self.file.extension() == Some("rs")
46    }
47}
48
49impl fmt::Display for ManifestPath {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        fmt::Display::fmt(&self.file, f)
52    }
53}
54
55impl ops::Deref for ManifestPath {
56    type Target = AbsPath;
57
58    fn deref(&self) -> &Self::Target {
59        &self.file
60    }
61}
62
63impl AsRef<AbsPath> for ManifestPath {
64    fn as_ref(&self) -> &AbsPath {
65        self.file.as_ref()
66    }
67}
68
69impl AsRef<std::path::Path> for ManifestPath {
70    fn as_ref(&self) -> &std::path::Path {
71        self.file.as_ref()
72    }
73}
74
75impl AsRef<std::ffi::OsStr> for ManifestPath {
76    fn as_ref(&self) -> &std::ffi::OsStr {
77        self.file.as_ref()
78    }
79}
80
81impl AsRef<Utf8Path> for ManifestPath {
82    fn as_ref(&self) -> &Utf8Path {
83        self.file.as_ref()
84    }
85}
86
87impl Borrow<AbsPath> for ManifestPath {
88    fn borrow(&self) -> &AbsPath {
89        self.file.borrow()
90    }
91}