duvet_core/
path.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use core::{cmp::Ordering, fmt};
5use serde::Deserialize;
6use std::{ffi::OsStr, ops::Deref, path::PathBuf, sync::Arc};
7
8#[derive(Clone, Deserialize)]
9#[serde(transparent)]
10pub struct Path {
11    path: Arc<OsStr>,
12}
13
14impl Path {
15    pub fn pop(&mut self) -> bool {
16        if let Some(parent) = self.parent() {
17            *self = parent.into();
18            true
19        } else {
20            false
21        }
22    }
23
24    pub fn push<V: AsRef<std::path::Path>>(&mut self, component: V) {
25        *self = self.join(component);
26    }
27
28    pub fn join<V: AsRef<std::path::Path>>(&self, component: V) -> Self {
29        self.as_ref().join(component).into()
30    }
31}
32
33impl PartialEq for Path {
34    fn eq(&self, other: &Self) -> bool {
35        self.as_ref().eq(other.as_ref())
36    }
37}
38
39impl Eq for Path {}
40
41impl PartialOrd for Path {
42    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
43        Some(self.cmp(other))
44    }
45}
46
47impl Ord for Path {
48    fn cmp(&self, other: &Self) -> Ordering {
49        self.as_ref().cmp(other.as_ref())
50    }
51}
52
53impl core::hash::Hash for Path {
54    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
55        self.as_ref().hash(state)
56    }
57}
58
59impl fmt::Debug for Path {
60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61        self.as_ref().fmt(f)
62    }
63}
64
65impl fmt::Display for Path {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        let path = self.as_ref();
68        let path = crate::env::current_dir()
69            .ok()
70            .and_then(|dir| path.strip_prefix(dir).ok())
71            .unwrap_or(path);
72        path.display().fmt(f)
73    }
74}
75
76impl Deref for Path {
77    type Target = std::path::Path;
78
79    fn deref(&self) -> &Self::Target {
80        std::path::Path::new(&self.path)
81    }
82}
83
84impl AsRef<std::path::Path> for Path {
85    fn as_ref(&self) -> &std::path::Path {
86        self
87    }
88}
89
90impl PartialEq<str> for Path {
91    fn eq(&self, other: &str) -> bool {
92        self.as_ref().eq(std::path::Path::new(other))
93    }
94}
95
96impl PartialEq<std::path::Path> for Path {
97    fn eq(&self, other: &std::path::Path) -> bool {
98        self.as_ref().eq(other)
99    }
100}
101
102impl From<String> for Path {
103    fn from(path: String) -> Self {
104        Self {
105            path: PathBuf::from(path).into_os_string().into(),
106        }
107    }
108}
109
110impl From<PathBuf> for Path {
111    fn from(path: PathBuf) -> Self {
112        Self {
113            path: path.into_os_string().into(),
114        }
115    }
116}
117
118impl From<&PathBuf> for Path {
119    fn from(path: &PathBuf) -> Self {
120        path.as_path().into()
121    }
122}
123
124impl From<&std::path::Path> for Path {
125    fn from(path: &std::path::Path) -> Self {
126        Self {
127            path: path.as_os_str().into(),
128        }
129    }
130}
131
132impl From<Path> for PathBuf {
133    fn from(value: Path) -> Self {
134        PathBuf::from(&value.path)
135    }
136}
137
138impl From<&Path> for Path {
139    fn from(path: &Path) -> Self {
140        Self {
141            path: path.as_os_str().into(),
142        }
143    }
144}
145
146impl From<&str> for Path {
147    fn from(path: &str) -> Self {
148        Self {
149            path: std::path::Path::new(path).as_os_str().into(),
150        }
151    }
152}