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 extension(&self) -> Option<&str> {
61 #[cfg(target_arch = "wasm32")]
62 {
63 self.0
64 .extension()
65 .map(|s| std::str::from_utf8(s).map(|s| s.trim_start_matches('.')).unwrap_or(""))
66 .filter(|s| !s.is_empty())
67 }
68 #[cfg(not(target_arch = "wasm32"))]
69 {
70 self.0.extension().and_then(|s| s.to_str())
71 }
72 }
73
74 pub fn join(&self, path: &str) -> Self {
75 #[cfg(target_arch = "wasm32")]
76 {
77 TypedPath(self.0.join(path))
78 }
79 #[cfg(not(target_arch = "wasm32"))]
80 {
81 TypedPath(self.0.join(path))
82 }
83 }
84
85 pub fn join_typed(&self, path: &TypedPath) -> Self {
86 #[cfg(target_arch = "wasm32")]
87 {
88 TypedPath(self.0.join(path.0.to_path()))
89 }
90 #[cfg(not(target_arch = "wasm32"))]
91 {
92 TypedPath(self.0.join(&path.0))
93 }
94 }
95
96 pub fn parent(&self) -> Option<Self> {
97 #[cfg(target_arch = "wasm32")]
98 {
99 self.0.parent().map(|p| TypedPath(p.to_path_buf()))
100 }
101 #[cfg(not(target_arch = "wasm32"))]
102 {
103 self.0.parent().map(|p| TypedPath(p.to_path_buf()))
104 }
105 }
106
107 pub fn to_string_lossy(&self) -> String {
108 #[cfg(target_arch = "wasm32")]
109 {
110 self.0.to_path().to_string_lossy().to_string()
111 }
112 #[cfg(not(target_arch = "wasm32"))]
113 {
114 self.0.to_string_lossy().to_string()
115 }
116 }
117
118 pub fn display(&self) -> String {
119 #[cfg(target_arch = "wasm32")]
120 {
121 self.0.to_path().display().to_string()
122 }
123 #[cfg(not(target_arch = "wasm32"))]
124 {
125 self.0.display().to_string()
126 }
127 }
128
129 pub fn file_name(&self) -> Option<String> {
130 #[cfg(target_arch = "wasm32")]
131 {
132 self.0
133 .file_name()
134 .map(|s| std::str::from_utf8(s).unwrap_or(""))
135 .filter(|s| !s.is_empty())
136 .map(|s| s.to_string())
137 }
138 #[cfg(not(target_arch = "wasm32"))]
139 {
140 self.0.file_name().and_then(|s| s.to_str()).map(|s| s.to_string())
141 }
142 }
143}
144
145impl serde::Serialize for TypedPath {
146 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
147 where
148 S: serde::Serializer,
149 {
150 #[cfg(target_arch = "wasm32")]
151 {
152 self.0.to_str().serialize(serializer)
153 }
154 #[cfg(not(target_arch = "wasm32"))]
155 {
156 self.0.serialize(serializer)
157 }
158 }
159}
160
161impl<'de> serde::de::Deserialize<'de> for TypedPath {
162 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
163 where
164 D: serde::Deserializer<'de>,
165 {
166 #[cfg(target_arch = "wasm32")]
167 {
168 let path: String = serde::Deserialize::deserialize(deserializer)?;
169 Ok(TypedPath(typed_path::TypedPath::derive(&path).to_path_buf()))
170 }
171 #[cfg(not(target_arch = "wasm32"))]
172 {
173 let path: std::path::PathBuf = serde::Deserialize::deserialize(deserializer)?;
174 Ok(TypedPath(path))
175 }
176 }
177}
178
179impl ts_rs::TS for TypedPath {
180 type WithoutGenerics = Self;
181
182 fn name() -> String {
183 "string".to_string()
184 }
185
186 fn decl() -> String {
187 std::path::PathBuf::decl()
188 }
189
190 fn decl_concrete() -> String {
191 std::path::PathBuf::decl_concrete()
192 }
193
194 fn inline() -> String {
195 std::path::PathBuf::inline()
196 }
197
198 fn inline_flattened() -> String {
199 std::path::PathBuf::inline_flattened()
200 }
201
202 fn output_path() -> Option<&'static std::path::Path> {
203 std::path::PathBuf::output_path()
204 }
205}
206
207impl schemars::JsonSchema for TypedPath {
208 fn schema_name() -> String {
209 "TypedPath".to_owned()
210 }
211
212 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
213 gen.subschema_for::<std::path::PathBuf>()
215 }
216}
217
218fn normalise_import<S: AsRef<str>>(raw: S) -> std::path::PathBuf {
224 let s = raw.as_ref();
225 if cfg!(unix) && s.contains('\\') {
228 std::path::PathBuf::from(s.replace('\\', "/"))
229 } else {
230 std::path::Path::new(s).to_path_buf()
231 }
232}