1use std::{
2 borrow::Borrow,
3 ops::{Deref, DerefMut},
4 path::{Path, PathBuf},
5 sync::Arc,
6};
7
8pub use camino::{Utf8Component, Utf8Components, Utf8Path, Utf8PathBuf, Utf8Prefix};
9use rspack_cacheable::{
10 cacheable,
11 with::{AsRefStr, AsRefStrConverter},
12};
13
14pub trait AssertUtf8 {
15 type Output;
16 fn assert_utf8(self) -> Self::Output;
17}
18
19impl AssertUtf8 for PathBuf {
20 type Output = Utf8PathBuf;
21
22 fn assert_utf8(self) -> Self::Output {
28 Utf8PathBuf::from_path_buf(self).unwrap_or_else(|p| {
29 panic!("expected UTF-8 path, got: {}", p.display());
30 })
31 }
32}
33
34impl<'a> AssertUtf8 for &'a Path {
35 type Output = &'a Utf8Path;
36
37 fn assert_utf8(self) -> Self::Output {
43 Utf8Path::from_path(self).unwrap_or_else(|| {
44 panic!("expected UTF-8 path, got: {}", self.display());
45 })
46 }
47}
48
49#[cacheable(with=AsRefStr, hashable)]
50#[derive(Clone, Debug, PartialEq, Eq, Hash)]
51pub struct ArcPath(Arc<Path>);
52
53impl Deref for ArcPath {
54 type Target = Arc<Path>;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl DerefMut for ArcPath {
62 fn deref_mut(&mut self) -> &mut Self::Target {
63 &mut self.0
64 }
65}
66
67impl From<PathBuf> for ArcPath {
68 fn from(value: PathBuf) -> Self {
69 ArcPath(value.into())
70 }
71}
72
73impl From<&Path> for ArcPath {
74 fn from(value: &Path) -> Self {
75 ArcPath(value.into())
76 }
77}
78
79impl From<&Utf8Path> for ArcPath {
80 fn from(value: &Utf8Path) -> Self {
81 ArcPath(value.as_std_path().into())
82 }
83}
84
85impl From<&ArcPath> for ArcPath {
86 fn from(value: &ArcPath) -> Self {
87 value.clone()
88 }
89}
90
91impl Borrow<Path> for ArcPath {
92 fn borrow(&self) -> &Path {
93 &self.0
94 }
95}
96
97impl AsRefStrConverter for ArcPath {
98 fn as_str(&self) -> &str {
99 self.0.to_str().expect("expect utf8 str")
100 }
101 fn from_str(s: &str) -> Self {
102 Self::from(Path::new(s))
103 }
104}
105
106fn _assert_size() {
107 use std::mem::size_of;
108 assert_eq!(size_of::<ArcPath>(), size_of::<[usize; 2]>());
109}