1use std::collections::TryReserveError;
2use std::env::current_dir;
3use std::ffi::{OsStr, OsString};
4use std::fmt::{Arguments, Display};
5use std::path::{Path, PathBuf};
6use std::cmp::Eq;
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
12pub struct PathBufD(PathBuf);
13
14impl PathBufD {
15    pub fn new() -> Self {
17        Self(PathBuf::new())
18    }
19
20    pub fn with_capacity(capacity: usize) -> Self {
22        Self(PathBuf::with_capacity(capacity))
23    }
24
25    pub fn current() -> Self {
27        Self(current_dir().unwrap_or(PathBuf::new()))
28    }
29
30    pub fn as_path(&self) -> &Path {
32        self.0.as_path()
33    }
34
35    pub fn as_bytes(&self) -> Vec<u8> {
37        self.to_string().as_bytes().to_owned()
38    }
39
40    pub fn push<P>(&mut self, path: P) -> ()
42    where
43        P: AsRef<Path>,
44    {
45        self.0.push(path)
46    }
47
48    pub fn join<P>(&self, path: P) -> Self
50    where
51        P: AsRef<Path>,
52    {
53        Self(self.0.join(path))
54    }
55
56    pub fn pop(&mut self) -> bool {
63        self.0.pop()
64    }
65
66    pub fn set_file_name<S>(&mut self, file_name: S)
70    where
71        S: AsRef<OsStr>,
72    {
73        self.0.set_file_name(file_name);
74    }
75
76    pub fn set_extension<S>(&mut self, extension: S)
80    where
81        S: AsRef<OsStr>,
82    {
83        self.0.set_extension(extension);
84    }
85
86    pub fn as_mut_os_string(&mut self) -> &mut OsString {
88        self.0.as_mut_os_string()
89    }
90
91    pub fn into_os_string(self) -> OsString {
93        self.0.into_os_string()
94    }
95
96    pub fn into_boxed_path(self) -> Box<Path> {
98        self.0.into_boxed_path()
99    }
100
101    pub fn capacity(&self) -> usize {
103        self.0.capacity()
104    }
105
106    pub fn clear(&mut self) -> () {
110        self.0.clear()
111    }
112
113    pub fn reserve(&mut self, additional: usize) -> () {
117        self.0.reserve(additional)
118    }
119
120    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
124        self.0.try_reserve(additional)
125    }
126
127    pub fn reserve_exact(&mut self, additional: usize) -> () {
131        self.0.reserve_exact(additional)
132    }
133
134    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
138        self.0.try_reserve_exact(additional)
139    }
140
141    pub fn shrink_to_fit(&mut self) {
145        self.0.shrink_to_fit()
146    }
147
148    pub fn shrink_to(&mut self, min_capacity: usize) -> () {
152        self.0.shrink_to(min_capacity)
153    }
154
155    pub fn extend<P>(self, paths: &[P]) -> Self
157    where
158        P: AsRef<Path>,
159    {
160        let mut buf = self;
161
162        for path in paths {
163            buf.push(path)
164        }
165
166        buf
167    }
168}
169
170impl Default for PathBufD {
171    fn default() -> Self {
172        Self(PathBuf::default())
173    }
174}
175
176impl Display for PathBufD {
177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178        write!(f, "{}", self.0.to_str().unwrap_or(""))
179    }
180}
181
182impl AsRef<Path> for PathBufD {
183    fn as_ref(&self) -> &Path {
184        self.as_path()
185    }
186}
187
188impl Into<PathBufD> for PathBuf {
189    fn into(self) -> PathBufD {
190        PathBufD(self)
191    }
192}
193
194impl From<PathBufD> for PathBuf {
195    fn from(value: PathBufD) -> Self {
196        value.0
197    }
198}
199
200pub fn pathbufd_fmt(args: Arguments) -> PathBufD {
203    let string = if let Some(s) = args.as_str() {
204        s
205    } else {
206        &args.to_string()
207    };
208
209    let mut pathbufd = PathBufD::new();
210    for split in string.split("/") {
211        if split.is_empty() {
212            pathbufd.push("/");
213            continue;
214        }
215
216        pathbufd.push(split);
217    }
218
219    return pathbufd;
220}
221
222#[macro_export]
223macro_rules! pathd {
224    ($($arg:tt)*) => {
225        pathbufd::pathbufd_fmt(std::format_args!($($arg)*)).to_string()
226    }
227}