1use derive_more::Debug;
2use serde::{de::Deserializer, Deserialize};
3use std::{
4 borrow::{Borrow, ToOwned},
5 marker::PhantomData,
6 ops::Deref,
7 path::{Path, PathBuf},
8 str::FromStr,
9};
10
11#[derive(Debug)]
12#[repr(transparent)]
13#[debug("{inner:?}")]
14pub struct Root<T: ?Sized> {
15 phantom: PhantomData<T>,
16 inner: Path,
17}
18
19impl<T: ?Sized> Root<T> {
20 pub fn new(inner: &Path) -> &Self {
21 let ptr = (inner as *const Path) as *const Root<T>;
22 unsafe { &*ptr }
23 }
24
25 pub fn join<U>(&self, path: impl AsRef<Path>) -> RootBuf<U> {
26 RootBuf::new(self.inner.join(path.as_ref()))
27 }
28
29 pub fn transmute<U>(&self) -> &Root<U> {
30 Root::<U>::new(&self.inner)
31 }
32}
33
34impl<T> Deref for Root<T> {
35 type Target = Path;
36 fn deref(&self) -> &Self::Target {
37 &self.inner
38 }
39}
40
41impl<T> AsRef<Root<T>> for Root<T> {
42 fn as_ref(&self) -> &Self {
43 self
44 }
45}
46
47impl<T> AsRef<Path> for Root<T> {
48 fn as_ref(&self) -> &Path {
49 &self.inner
50 }
51}
52
53impl<T> ToOwned for Root<T> {
54 type Owned = RootBuf<T>;
55
56 fn to_owned(&self) -> Self::Owned {
57 Self::Owned::new(self.inner.to_owned())
58 }
59
60 fn clone_into(&self, target: &mut Self::Owned) {
62 self.inner.clone_into(&mut target.inner)
63 }
64}
65
66#[derive(Debug)]
67#[repr(transparent)]
68#[debug("{inner:?}")]
69pub struct RootBuf<T: ?Sized> {
70 phantom: PhantomData<T>,
71 inner: PathBuf,
72}
73
74impl<T: ?Sized> RootBuf<T> {
75 pub fn new(inner: PathBuf) -> Self {
76 Self {
77 inner,
78 phantom: PhantomData,
79 }
80 }
81
82 pub fn into_path_buf(self) -> PathBuf {
83 self.inner
84 }
85
86 pub fn join<U>(&self, path: impl AsRef<Path>) -> RootBuf<U> {
87 RootBuf::new(self.inner.join(path.as_ref()))
88 }
89
90 pub fn as_root(&self) -> &Root<T> {
91 Root::new(self.inner.as_path())
92 }
93}
94
95impl<T> Deref for RootBuf<T> {
96 type Target = Root<T>;
97 fn deref(&self) -> &Self::Target {
98 self.as_root()
99 }
100}
101
102impl<T> AsRef<Root<T>> for RootBuf<T> {
103 fn as_ref(&self) -> &Root<T> {
104 self.as_root()
105 }
106}
107
108impl<T> AsRef<Path> for RootBuf<T> {
109 fn as_ref(&self) -> &Path {
110 self.inner.as_ref()
111 }
112}
113
114impl<T> Borrow<Root<T>> for RootBuf<T> {
115 fn borrow(&self) -> &Root<T> {
116 self.as_root()
117 }
118}
119
120impl<T> Clone for RootBuf<T> {
121 fn clone(&self) -> Self {
122 Self::new(self.inner.clone())
123 }
124}
125
126impl<'de, T> Deserialize<'de> for RootBuf<T> {
127 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128 where
129 D: Deserializer<'de>,
130 {
131 Ok(Self::new(PathBuf::deserialize(deserializer)?))
132 }
133}
134
135impl<T> FromStr for RootBuf<T> {
136 type Err = <PathBuf as FromStr>::Err;
137 fn from_str(value: &str) -> Result<Self, Self::Err> {
138 Ok(Self::new(PathBuf::from_str(value)?))
139 }
140}
141
142impl<T> TryFrom<String> for RootBuf<T> {
143 type Error = <RootBuf<T> as FromStr>::Err;
144 fn try_from(from: String) -> Result<Self, Self::Error> {
145 Self::from_str(from.as_str())
146 }
147}