firewood_storage/path/
buf.rs1use crate::{ComponentIter, IntoSplitPath, PathComponent, TriePath};
5
6pub type PathBuf = smallvec::SmallVec<[PathComponent; 32]>;
8
9pub enum PartialPath<'a> {
11 Borrowed(&'a [PathComponent]),
13
14 Owned(PathBuf),
16}
17
18impl std::fmt::Debug for PartialPath<'_> {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 self.display().fmt(f)
21 }
22}
23
24impl std::fmt::Display for PartialPath<'_> {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 self.display().fmt(f)
27 }
28}
29
30impl PartialPath<'_> {
31 #[inline]
33 #[must_use]
34 pub fn as_slice(&self) -> &[PathComponent] {
35 match self {
36 PartialPath::Borrowed(slice) => slice,
37 PartialPath::Owned(buf) => buf.as_slice(),
38 }
39 }
40
41 #[inline]
47 #[must_use]
48 pub fn into_owned(self) -> PathBuf {
49 match self {
50 PartialPath::Borrowed(slice) => slice.into(),
51 PartialPath::Owned(buf) => buf,
52 }
53 }
54
55 #[inline]
57 #[must_use]
58 pub const fn is_borrowed(&self) -> bool {
59 matches!(self, PartialPath::Borrowed(_))
60 }
61
62 #[inline]
64 #[must_use]
65 pub const fn is_owned(&self) -> bool {
66 matches!(self, PartialPath::Owned(_))
67 }
68
69 pub fn to_mut(&mut self) -> &mut PathBuf {
72 if let Self::Borrowed(buf) = self {
73 *self = Self::Owned((*buf).into());
74 }
75
76 if let Self::Owned(buf) = self {
77 buf
78 } else {
79 unreachable!()
80 }
81 }
82}
83
84impl std::ops::Deref for PartialPath<'_> {
85 type Target = [PathComponent];
86
87 fn deref(&self) -> &Self::Target {
88 self.as_slice()
89 }
90}
91
92impl std::borrow::Borrow<[PathComponent]> for PartialPath<'_> {
93 fn borrow(&self) -> &[PathComponent] {
94 self.as_slice()
95 }
96}
97
98impl AsRef<[PathComponent]> for PartialPath<'_> {
99 fn as_ref(&self) -> &[PathComponent] {
100 self.as_slice()
101 }
102}
103
104impl TriePath for PartialPath<'_> {
105 type Components<'a>
106 = ComponentIter<'a>
107 where
108 Self: 'a;
109
110 fn len(&self) -> usize {
111 self.as_slice().len()
112 }
113
114 fn components(&self) -> Self::Components<'_> {
115 self.as_slice().iter().copied()
116 }
117
118 fn as_component_slice(&self) -> PartialPath<'_> {
119 PartialPath::Borrowed(self.as_slice())
120 }
121}
122
123impl<'a> IntoSplitPath for &'a PartialPath<'_> {
124 type Path = &'a [PathComponent];
125
126 #[inline]
127 fn into_split_path(self) -> Self::Path {
128 self
129 }
130}
131
132#[must_use]
138pub struct PathGuard<'a> {
139 buf: &'a mut PathBuf,
140 len: usize,
141}
142
143impl std::fmt::Debug for PathGuard<'_> {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 self.buf.display().fmt(f)
146 }
147}
148
149impl Drop for PathGuard<'_> {
150 fn drop(&mut self) {
151 self.buf.truncate(self.len);
152 }
153}
154
155impl<'a> PathGuard<'a> {
156 pub fn new(buf: &'a mut PathBuf) -> Self {
159 Self {
160 len: buf.len(),
161 buf,
162 }
163 }
164
165 pub fn fork(&mut self) -> PathGuard<'_> {
170 PathGuard::new(self.buf)
171 }
172
173 pub fn fork_append(&mut self, path: impl TriePath) -> PathGuard<'_> {
181 let mut fork = self.fork();
182 fork.extend(path.components());
183 fork
184 }
185
186 pub fn push(&mut self, component: PathComponent) {
190 self.buf.push(component);
191 }
192}
193
194impl std::ops::Deref for PathGuard<'_> {
195 type Target = PathBuf;
196
197 fn deref(&self) -> &Self::Target {
198 self.buf
199 }
200}
201
202impl Extend<PathComponent> for PathGuard<'_> {
203 fn extend<T: IntoIterator<Item = PathComponent>>(&mut self, iter: T) {
204 self.buf.extend(iter);
205 }
206}