GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: MIT
4
5use crate::gitroot::{get, with_plugin, with_plugin_reporter};
6use crate::ptr::{ptr_to_string, string_to_ptr};
7use crate::{Commit, ConfPlugin, Report};
8use std::mem::MaybeUninit;
9
10#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "init"))]
11pub fn init(
12 repo_name_ptr: u32,
13 repo_name_size: u32,
14 conf_has_changed_ptr: u32,
15 conf_has_changed_size: u32,
16 conf_ptr: u32,
17 conf_size: u32,
18) {
19 let repo_name = ptr_to_string(repo_name_ptr, repo_name_size);
20 let conf_has_changed = ptr_to_string(conf_has_changed_ptr, conf_has_changed_size) == "true";
21 let conf = ptr_to_string(conf_ptr, conf_size);
22 with_plugin(|plugin| plugin.init(repo_name, conf_has_changed, conf));
23}
24
25#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "startCommit"))]
26pub fn start_commit(json: &str) {
27 let commit: Commit = serde_json::from_str(json).expect("JSON was not well-formatted");
28 with_plugin(|plugin| plugin.start_commit(commit));
29}
30
31#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "addFile"))]
32pub fn add_file(filepath: &str) {
33 with_plugin(|plugin| plugin.add_file(String::from(filepath)));
34}
35
36#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "modFile"))]
37pub fn mod_file(from_filepath: &str, to_filepath: &str) {
38 with_plugin(|plugin| plugin.mod_file(String::from(from_filepath), String::from(to_filepath)));
39}
40
41#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "delFile"))]
42pub fn del_file(filepath: &str) {
43 with_plugin(|plugin| plugin.del_file(String::from(filepath)));
44}
45
46#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "endCommit"))]
47pub fn end_commit(json: &str) {
48 let commit: Commit = serde_json::from_str(json).expect("JSON was not well-formatted");
49 with_plugin(|plugin| plugin.end_commit(commit));
50}
51
52#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "finish"))]
53pub fn finish() {
54 with_plugin(|plugin| plugin.finish());
55}
56
57#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "report"))]
58pub fn report(json: &str) {
59 let report: Report = serde_json::from_str(json).expect("JSON was not well-formatted");
60 with_plugin_reporter(|plugin| plugin.report(report));
61}
62
63/// # Safety
64///
65/// Called by host
66#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "pluginConf"))]
67pub unsafe extern "C" fn plugin_conf() -> u64 {
68 let conf_plugin = ConfPlugin {
69 default_run: get().run.clone(),
70 sdk_version: String::from("0.3.0"),
71 sdk_type: String::from("tinygo"),
72 };
73 let conf = serde_json::to_string(&conf_plugin).unwrap();
74 let (ptr, len) = string_to_ptr(&conf);
75 // Note: This changes ownership of the pointer to the external caller. If
76 // we didn't call forget, the caller would read back a corrupt value. Since
77 // we call forget, the caller must deallocate externally to prevent leaks.
78 std::mem::forget(conf);
79 ((ptr as u64) << 32) | len as u64
80}
81
82#[unsafe(no_mangle)]
83extern "C" fn gitrootAlloc(size: u32) -> *mut u8 {
84 // Allocate the amount of bytes needed.
85 let vec: Vec<MaybeUninit<u8>> = vec![MaybeUninit::uninit(); size as usize];
86 // into_raw leaks the memory to the caller.
87 Box::into_raw(vec.into_boxed_slice()) as *mut u8
88}
89
90#[unsafe(no_mangle)]
91extern "C" fn gitrootFree(ptr: u32, size: u32) {
92 unsafe {
93 let _ = Vec::from_raw_parts(ptr as *mut u8, 0, size as usize);
94 }
95}