kcl_lib/execution/
typed_path.rs1#[derive(Clone, Debug, PartialEq, Eq, Hash)]
5pub struct TypedPath(
6 #[cfg(target_arch = "wasm32")] pub typed_path::TypedPathBuf,
7 #[cfg(not(target_arch = "wasm32"))] pub std::path::PathBuf,
8);
9
10impl std::fmt::Display for TypedPath {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 #[cfg(target_arch = "wasm32")]
13 {
14 self.0.to_path().display().fmt(f)
15 }
16 #[cfg(not(target_arch = "wasm32"))]
17 {
18 self.0.display().fmt(f)
19 }
20 }
21}
22
23impl Default for TypedPath {
24 fn default() -> Self {
25 #[cfg(target_arch = "wasm32")]
26 {
27 TypedPath(typed_path::TypedPath::derive("").to_path_buf())
28 }
29 #[cfg(not(target_arch = "wasm32"))]
30 {
31 TypedPath(std::path::PathBuf::new())
32 }
33 }
34}
35
36impl From<&String> for TypedPath {
37 fn from(path: &String) -> Self {
38 TypedPath::new(path)
39 }
40}
41
42impl From<&str> for TypedPath {
43 fn from(path: &str) -> Self {
44 TypedPath::new(path)
45 }
46}
47
48impl TypedPath {
49 pub fn new(path: &str) -> Self {
50 #[cfg(target_arch = "wasm32")]
51 {
52 TypedPath(typed_path::TypedPath::derive(path).to_path_buf())
53 }
54 #[cfg(not(target_arch = "wasm32"))]
55 {
56 TypedPath(normalise_import(path))
57 }
58 }
59
60 pub fn starts_with(&self, base: &TypedPath) -> bool {
61 #[cfg(target_arch = "wasm32")]
62 {
63 self.0.starts_with(base.0.as_ref())
64 }
65 #[cfg(not(target_arch = "wasm32"))]
66 {
67 self.0.starts_with(&base.0)
68 }
69 }
70
71 pub fn extension(&self) -> Option<&str> {
72 #[cfg(target_arch = "wasm32")]
73 {
74 self.0
75 .extension()
76 .map(|s| std::str::from_utf8(s).map(|s| s.trim_start_matches('.')).unwrap_or(""))
77 .filter(|s| !s.is_empty())
78 }
79 #[cfg(not(target_arch = "wasm32"))]
80 {
81 self.0.extension().and_then(|s| s.to_str())
82 }
83 }
84
85 pub fn is_absolute(&self) -> bool {
86 self.0.is_absolute()
87 }
88
89 pub fn join(&self, path: &str) -> Self {
90 #[cfg(target_arch = "wasm32")]
91 {
92 TypedPath(self.0.join(path))
93 }
94 #[cfg(not(target_arch = "wasm32"))]
95 {
96 TypedPath(self.0.join(path))
97 }
98 }
99
100 pub fn join_typed(&self, path: &TypedPath) -> Self {
101 #[cfg(target_arch = "wasm32")]
102 {
103 TypedPath(self.0.join(path.0.to_path()))
104 }
105 #[cfg(not(target_arch = "wasm32"))]
106 {
107 TypedPath(self.0.join(&path.0))
108 }
109 }
110
111 pub fn parent(&self) -> Option<Self> {
112 #[cfg(target_arch = "wasm32")]
113 {
114 self.0.parent().map(|p| TypedPath(p.to_path_buf()))
115 }
116 #[cfg(not(target_arch = "wasm32"))]
117 {
118 self.0.parent().map(|p| TypedPath(p.to_path_buf()))
119 }
120 }
121
122 #[cfg(not(target_arch = "wasm32"))]
123 pub fn strip_prefix(&self, base: impl AsRef<std::path::Path>) -> Result<Self, std::path::StripPrefixError> {
124 self.0.strip_prefix(base).map(|p| TypedPath(p.to_path_buf()))
125 }
126
127 #[cfg(not(target_arch = "wasm32"))]
128 pub fn canonicalize(&self) -> Result<Self, std::io::Error> {
129 self.0.canonicalize().map(TypedPath)
130 }
131
132 pub fn to_string_lossy(&self) -> String {
133 #[cfg(target_arch = "wasm32")]
134 {
135 self.0.to_path().to_string_lossy().to_string()
136 }
137 #[cfg(not(target_arch = "wasm32"))]
138 {
139 self.0.to_string_lossy().to_string()
140 }
141 }
142
143 pub fn display(&self) -> String {
144 #[cfg(target_arch = "wasm32")]
145 {
146 self.0.to_path().display().to_string()
147 }
148 #[cfg(not(target_arch = "wasm32"))]
149 {
150 self.0.display().to_string()
151 }
152 }
153
154 pub fn file_name(&self) -> Option<String> {
155 #[cfg(target_arch = "wasm32")]
156 {
157 self.0
158 .file_name()
159 .map(|s| std::str::from_utf8(s).unwrap_or(""))
160 .filter(|s| !s.is_empty())
161 .map(|s| s.to_string())
162 }
163 #[cfg(not(target_arch = "wasm32"))]
164 {
165 self.0.file_name().and_then(|s| s.to_str()).map(|s| s.to_string())
166 }
167 }
168}
169
170impl serde::Serialize for TypedPath {
171 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
172 where
173 S: serde::Serializer,
174 {
175 #[cfg(target_arch = "wasm32")]
176 {
177 self.0.to_str().serialize(serializer)
178 }
179 #[cfg(not(target_arch = "wasm32"))]
180 {
181 self.0.serialize(serializer)
182 }
183 }
184}
185
186impl<'de> serde::de::Deserialize<'de> for TypedPath {
187 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
188 where
189 D: serde::Deserializer<'de>,
190 {
191 #[cfg(target_arch = "wasm32")]
192 {
193 let path: String = serde::Deserialize::deserialize(deserializer)?;
194 Ok(TypedPath(typed_path::TypedPath::derive(&path).to_path_buf()))
195 }
196 #[cfg(not(target_arch = "wasm32"))]
197 {
198 let path: std::path::PathBuf = serde::Deserialize::deserialize(deserializer)?;
199 Ok(TypedPath(path))
200 }
201 }
202}
203
204impl ts_rs::TS for TypedPath {
205 type WithoutGenerics = Self;
206 type OptionInnerType = Self;
207
208 fn name(_: &ts_rs::Config) -> String {
209 "string".to_string()
210 }
211
212 fn decl(config: &ts_rs::Config) -> String {
213 std::path::PathBuf::decl(config)
214 }
215
216 fn decl_concrete(config: &ts_rs::Config) -> String {
217 std::path::PathBuf::decl_concrete(config)
218 }
219
220 fn inline(config: &ts_rs::Config) -> String {
221 std::path::PathBuf::inline(config)
222 }
223
224 fn inline_flattened(config: &ts_rs::Config) -> String {
225 std::path::PathBuf::inline_flattened(config)
226 }
227
228 fn output_path() -> Option<std::path::PathBuf> {
229 std::path::PathBuf::output_path()
230 }
231}
232
233#[cfg(not(target_arch = "wasm32"))]
239fn normalise_import<S: AsRef<str>>(raw: S) -> std::path::PathBuf {
240 let s = raw.as_ref();
241 if cfg!(unix) && s.contains('\\') {
244 std::path::PathBuf::from(s.replace('\\', "/"))
245 } else {
246 std::path::Path::new(s).to_path_buf()
247 }
248}