1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: MIT
4
5use crate::{
6 fs::FsBase,
7 model::{
8 Call, CallRes, Commit, Exec, ExecStatus, ForgeConf, HttpRequest, HttpResponse,
9 IteratorItem, ReportToGitroot,
10 },
11 ptr::{ptr_to_string, string_to_ptr},
12};
13
14#[link(wasm_import_module = "gitroot")]
15unsafe extern "C" {
16 #[link_name = "forgeConf"]
17 pub unsafe fn _forge_conf() -> u64;
18 #[link_name = "modifyContent"]
19 pub unsafe fn _modify_content(
20 filepathPtr: u32,
21 filepathSize: u32,
22 contentPtr: u32,
23 contentSize: u32,
24 );
25 #[link_name = "modifyWebContent"]
26 pub unsafe fn _modify_web_content(
27 filepathPtr: u32,
28 filepathSize: u32,
29 contentPtr: u32,
30 contentSize: u32,
31 );
32 #[link_name = "replaceWebContent"]
33 pub unsafe fn _replace_web_content(
34 filepathPtr: u32,
35 filepathSize: u32,
36 oldContentPtr: u32,
37 oldContentSize: u32,
38 contentPtr: u32,
39 contentSize: u32,
40 );
41 #[link_name = "modifyCacheContent"]
42 pub unsafe fn _modify_cache_content(
43 filepathPtr: u32,
44 filepathSize: u32,
45 contentPtr: u32,
46 contentSize: u32,
47 );
48
49 #[link_name = "copyFile"]
50 pub unsafe fn _copy_file(
51 from_fs_ptr: u32,
52 from_fs_size: u32,
53 from_path_ptr: u32,
54 from_path_size: u32,
55 to_fs_ptr: u32,
56 to_fs_size: u32,
57 to_path_ptr: u32,
58 to_path_size: u32,
59 ) -> u64;
60
61 #[link_name = "deleteFile"]
62 pub unsafe fn _delete_file(
63 from_fs_ptr: u32,
64 from_fs_size: u32,
65 from_path_ptr: u32,
66 from_path_size: u32,
67 ) -> u64;
68
69 #[link_name = "moveFile"]
70 pub unsafe fn _move_file(
71 from_fs_ptr: u32,
72 from_fs_size: u32,
73 from_path_ptr: u32,
74 from_path_size: u32,
75 to_fs_ptr: u32,
76 to_fs_size: u32,
77 to_path_ptr: u32,
78 to_path_size: u32,
79 ) -> u64;
80
81 #[link_name = "replaceContent"]
82 pub unsafe fn _replace_content(
83 from_fs_ptr: u32,
84 from_fs_size: u32,
85 filepath_ptr: u32,
86 filepath_size: u32,
87 old_content_ptr: u32,
88 old_content_size: u32,
89 content_ptr: u32,
90 content_size: u32,
91 ) -> u64;
92
93 #[link_name = "writeContent"]
94 pub unsafe fn _write_content(
95 from_fs_ptr: u32,
96 from_fs_size: u32,
97 filepath_ptr: u32,
98 filepath_size: u32,
99 content_ptr: u32,
100 content_size: u32,
101 ) -> u64;
102 #[link_name = "commitAll"]
103 pub unsafe fn _commit_all(ptr: u32, size: u32);
104 #[link_name = "diffWithParent"]
105 pub unsafe fn _diff_with_parent(
106 hash_ptr: u32,
107 hash_size: u32,
108 oldfile_ptr: u32,
109 oldfile_size: u32,
110 newfile_ptr: u32,
111 newfile_size: u32,
112 ) -> u64;
113 #[link_name = "log"]
114 pub unsafe fn _log(ptr: u32, size: u32);
115 #[link_name = "logError"]
116 pub unsafe fn _log_error(messagePtr: u32, messageSize: u32, errPtr: u32, errSize: u32);
117 #[link_name = "merge"]
118 pub unsafe fn _merge(from_ptr: u32, from_size: u32, to_ptr: u32, to_size: u32);
119 #[link_name = "commits"]
120 pub unsafe fn _commits(from_ptr: u32, from_size: u32, to_ptr: u32, to_size: u32) -> u64;
121 #[link_name = "exec"]
122 pub unsafe fn _exec(cmd_ptr: u32, cmd_size: u32) -> u64;
123 #[link_name = "report"]
124 pub unsafe fn _report(report_ptr: u32, report_size: u32);
125 #[link_name = "canCall"]
126 pub unsafe fn _can_call(report_ptr: u32, report_size: u32) -> u32;
127 #[link_name = "call"]
128 pub unsafe fn _call(report_ptr: u32, report_size: u32) -> u64;
129 #[link_name = "httpClient"]
130 pub unsafe fn _http_client(ptr: u32, size: u32) -> u64;
131 #[link_name = "iteratorNext"]
132 pub unsafe fn _iterator_next(ptr: u32, size: u32) -> u64;
133}
134
135pub(crate) fn forge_conf() -> Result<ForgeConf, String> {
136 unsafe {
137 let ptr_size: u64 = _forge_conf();
138 if ptr_size == 0 {
139 return Err(String::from("can't get forge_conf"));
140 }
141 let ptr: u32 = (ptr_size >> 32) as u32;
142 let size: u32 = ptr_size as u32;
143 Ok(serde_json::from_str(ptr_to_string(ptr, size).as_str())
144 .expect("JSON was not well-formatted"))
145 }
146}
147
148pub(crate) fn copy_file(
149 from_fs: FsBase,
150 from_path: String,
151 to_fs: FsBase,
152 to_path: String,
153) -> Result<(), String> {
154 let (from_fs_ptr, from_fs_size) = string_to_ptr(from_fs.as_str());
155 let (from_path_ptr, from_path_size) = string_to_ptr(&from_path);
156 let (to_fs_ptr, to_fs_size) = string_to_ptr(to_fs.as_str());
157 let (to_path_ptr, to_path_size) = string_to_ptr(&to_path);
158 unsafe {
159 let ptr_size: u64 = _copy_file(
160 from_fs_ptr,
161 from_fs_size,
162 from_path_ptr,
163 from_path_size,
164 to_fs_ptr,
165 to_fs_size,
166 to_path_ptr,
167 to_path_size,
168 );
169 if ptr_size == 0 {
170 return Ok(());
171 }
172 let ptr: u32 = (ptr_size >> 32) as u32;
173 let size: u32 = ptr_size as u32;
174 Err(ptr_to_string(ptr, size))
175 }
176}
177
178pub(crate) fn delete_file(from_fs: FsBase, from_path: String) -> Result<(), String> {
179 let (from_fs_ptr, from_fs_size) = string_to_ptr(from_fs.as_str());
180 let (from_path_ptr, from_path_size) = string_to_ptr(&from_path);
181 unsafe {
182 let ptr_size: u64 = _delete_file(from_fs_ptr, from_fs_size, from_path_ptr, from_path_size);
183 if ptr_size == 0 {
184 return Ok(());
185 }
186 let ptr: u32 = (ptr_size >> 32) as u32;
187 let size: u32 = ptr_size as u32;
188 Err(ptr_to_string(ptr, size))
189 }
190}
191
192pub(crate) fn move_file(
193 from_fs: FsBase,
194 from_path: String,
195 to_fs: FsBase,
196 to_path: String,
197) -> Result<(), String> {
198 let (from_fs_ptr, from_fs_size) = string_to_ptr(from_fs.as_str());
199 let (from_path_ptr, from_path_size) = string_to_ptr(&from_path);
200 let (to_fs_ptr, to_fs_size) = string_to_ptr(to_fs.as_str());
201 let (to_path_ptr, to_path_size) = string_to_ptr(&to_path);
202 unsafe {
203 let ptr_size: u64 = _move_file(
204 from_fs_ptr,
205 from_fs_size,
206 from_path_ptr,
207 from_path_size,
208 to_fs_ptr,
209 to_fs_size,
210 to_path_ptr,
211 to_path_size,
212 );
213 if ptr_size == 0 {
214 return Ok(());
215 }
216 let ptr: u32 = (ptr_size >> 32) as u32;
217 let size: u32 = ptr_size as u32;
218 Err(ptr_to_string(ptr, size))
219 }
220}
221
222pub(crate) fn replace_content(
223 from_fs: FsBase,
224 filepath: String,
225 old_content: String,
226 content: String,
227) -> Result<(), String> {
228 let (from_fs_ptr, from_fs_size) = string_to_ptr(from_fs.as_str());
229 let (filepath_ptr, filepath_size) = string_to_ptr(&filepath);
230 let (old_content_ptr, old_content_size) = string_to_ptr(&old_content);
231 let (content_ptr, content_size) = string_to_ptr(&content);
232 unsafe {
233 let ptr_size: u64 = _replace_content(
234 from_fs_ptr,
235 from_fs_size,
236 filepath_ptr,
237 filepath_size,
238 old_content_ptr,
239 old_content_size,
240 content_ptr,
241 content_size,
242 );
243 if ptr_size == 0 {
244 return Ok(());
245 }
246 let ptr: u32 = (ptr_size >> 32) as u32;
247 let size: u32 = ptr_size as u32;
248 Err(ptr_to_string(ptr, size))
249 }
250}
251
252pub(crate) fn write_content(
253 from_fs: FsBase,
254 filepath: String,
255 content: String,
256) -> Result<(), String> {
257 let (from_fs_ptr, from_fs_size) = string_to_ptr(from_fs.as_str());
258 let (filepath_ptr, filepath_size) = string_to_ptr(&filepath);
259 let (content_ptr, content_size) = string_to_ptr(&content);
260 unsafe {
261 let ptr_size: u64 = _write_content(
262 from_fs_ptr,
263 from_fs_size,
264 filepath_ptr,
265 filepath_size,
266 content_ptr,
267 content_size,
268 );
269 if ptr_size == 0 {
270 return Ok(());
271 }
272 let ptr: u32 = (ptr_size >> 32) as u32;
273 let size: u32 = ptr_size as u32;
274 Err(ptr_to_string(ptr, size))
275 }
276}
277
278pub(crate) fn commit_all(message: String) {
279 let (msg_ptr, msg_size) = string_to_ptr(&message);
280 unsafe {
281 _commit_all(msg_ptr, msg_size);
282 }
283}
284
285pub(crate) fn diff_with_parent(
286 hash: String,
287 oldfile: String,
288 newfile: String,
289) -> Result<String, String> {
290 let (hash_ptr, hash_size) = string_to_ptr(&hash);
291 let (oldfile_ptr, oldfile_size) = string_to_ptr(&oldfile);
292 let (newfile_ptr, newfile_size) = string_to_ptr(&newfile);
293 unsafe {
294 let ptr_size = _diff_with_parent(
295 hash_ptr,
296 hash_size,
297 oldfile_ptr,
298 oldfile_size,
299 newfile_ptr,
300 newfile_size,
301 );
302 if ptr_size == 0 {
303 return Err(String::from("can't get diff_with_parent"));
304 }
305 let ptr: u32 = (ptr_size >> 32) as u32;
306 let size: u32 = ptr_size as u32;
307 Ok(ptr_to_string(ptr, size))
308 }
309}
310
311pub(crate) fn log(message: &str) {
312 let (msg_ptr, msg_size) = string_to_ptr(message);
313 unsafe {
314 _log(msg_ptr, msg_size);
315 }
316}
317
318pub(crate) fn log_error(message: &str, err: &str) {
319 let (msg_ptr, msg_size) = string_to_ptr(message);
320 let (err_ptr, err_size) = string_to_ptr(err);
321 unsafe {
322 _log_error(msg_ptr, msg_size, err_ptr, err_size);
323 }
324}
325
326pub(crate) fn merge(from: String, to: String) {
327 let (from_ptr, from_size) = string_to_ptr(&from);
328 let (to_ptr, to_size) = string_to_ptr(&to);
329 unsafe {
330 _merge(from_ptr, from_size, to_ptr, to_size);
331 }
332}
333
334pub(crate) fn commits(from: String, to: String) -> Result<Vec<Commit>, String> {
335 let (from_ptr, from_size) = string_to_ptr(&from);
336 let (to_ptr, to_size) = string_to_ptr(&to);
337 unsafe {
338 let ptr_size = _commits(from_ptr, from_size, to_ptr, to_size);
339 if ptr_size == 0 {
340 return Err(String::from("can't get commits"));
341 }
342 let ptr: u32 = (ptr_size >> 32) as u32;
343 let size: u32 = ptr_size as u32;
344 Ok(serde_json::from_str(ptr_to_string(ptr, size).as_str())
345 .expect("JSON was not well-formatted"))
346 }
347}
348
349pub(crate) fn exec(exec: &Exec) -> Result<ExecStatus, String> {
350 let exec_json = serde_json::to_string(&exec).unwrap();
351 let (cmd_ptr, cmd_size) = string_to_ptr(&exec_json);
352 unsafe {
353 let ptr_size = _exec(cmd_ptr, cmd_size);
354 if ptr_size == 0 {
355 return Err(String::from("can't exec"));
356 }
357 let ptr: u32 = (ptr_size >> 32) as u32;
358 let size: u32 = ptr_size as u32;
359 Ok(serde_json::from_str(ptr_to_string(ptr, size).as_str())
360 .expect("JSON was not well-formatted"))
361 }
362}
363
364pub(crate) fn report_to_gitroot(report: ReportToGitroot) {
365 let report_json = serde_json::to_string(&report).unwrap();
366 let (cmd_ptr, cmd_size) = string_to_ptr(&report_json);
367 unsafe {
368 _report(cmd_ptr, cmd_size);
369 }
370}
371
372pub(crate) fn can_call(call: &Call) -> u32 {
373 let call_json = serde_json::to_string(&call).unwrap();
374 let (ptr, size) = string_to_ptr(&call_json);
375 unsafe { _can_call(ptr, size) }
376}
377
378pub(crate) fn call(call: &Call) -> Result<CallRes, String> {
379 let call_json = serde_json::to_string(&call).unwrap();
380 let (ptr, size) = string_to_ptr(&call_json);
381 unsafe {
382 let ptr_size = _call(ptr, size);
383 if ptr_size == 0 {
384 return Err(String::from("can't call"));
385 }
386 let ptr: u32 = (ptr_size >> 32) as u32;
387 let size: u32 = ptr_size as u32;
388 Ok(serde_json::from_str(ptr_to_string(ptr, size).as_str())
389 .expect("JSON was not well-formatted"))
390 }
391}
392
393pub(crate) fn http_client(request: &HttpRequest) -> Result<HttpResponse, String> {
394 let request_json = serde_json::to_string(&request).unwrap();
395 let (ptr, size) = string_to_ptr(&request_json);
396 unsafe {
397 let ptr_size = _http_client(ptr, size);
398 if ptr_size == 0 {
399 return Err(String::from("can't http"));
400 }
401 let ptr: u32 = (ptr_size >> 32) as u32;
402 let size: u32 = ptr_size as u32;
403 Ok(serde_json::from_str(ptr_to_string(ptr, size).as_str())
404 .expect("JSON was not well-formatted"))
405 }
406}
407
408pub(crate) fn iterator_next(ptr: u32, size: u32) -> Result<IteratorItem, String> {
409 unsafe {
410 let ptr_size = _iterator_next(ptr, size);
411 if ptr_size == 0 {
412 return Err(String::from("can't iterator_next"));
413 }
414 let ptr: u32 = (ptr_size >> 32) as u32;
415 let size: u32 = ptr_size as u32;
416 Ok(serde_json::from_str(ptr_to_string(ptr, size).as_str())
417 .expect("JSON was not well-formatted"))
418 }
419}