Skip to main content

maelstrom_util/
root.rs

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    // Provided method
61    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}