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::{Commit, ConfPlugin, Server};
6use crate::ptr::{ptr_to_string, string_to_ptr};
7use std::mem::MaybeUninit;
8
9#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "init"))]
10pub fn init(
11 repo_name_ptr: u32,
12 repo_name_size: u32,
13 conf_has_changed_ptr: u32,
14 conf_has_changed_size: u32,
15 conf_ptr: u32,
16 conf_size: u32,
17) {
18 let repo_name = ptr_to_string(repo_name_ptr, repo_name_size);
19 let conf_has_changed =
20 ptr_to_string(conf_has_changed_ptr, conf_has_changed_size) == String::from("true");
21 let conf = ptr_to_string(conf_ptr, conf_size);
22 Server::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 Server::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 Server::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 Server::with_plugin(|plugin| {
39 plugin.mod_file(String::from(from_filepath), String::from(to_filepath))
40 });
41}
42
43#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "delFile"))]
44pub fn del_file(filepath: &str) {
45 Server::with_plugin(|plugin| plugin.del_file(String::from(filepath)));
46}
47
48#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "endCommit"))]
49pub fn end_commit(json: &str) {
50 let commit: Commit = serde_json::from_str(json).expect("JSON was not well-formatted");
51 Server::with_plugin(|plugin| plugin.end_commit(commit));
52}
53
54#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "finish"))]
55pub fn finish() {
56 Server::with_plugin(|plugin| plugin.finish());
57}
58
59#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "pluginConf"))]
60pub unsafe extern "C" fn plugin_conf() -> u64 {
61 let conf_plugin = ConfPlugin {
62 default_run: Server::get().run.clone(),
63 sdk_version: String::from("0.3.0"),
64 sdk_type: String::from("tinygo"),
65 };
66 let conf = serde_json::to_string(&conf_plugin).unwrap();
67 let (ptr, len) = string_to_ptr(&conf);
68 // Note: This changes ownership of the pointer to the external caller. If
69 // we didn't call forget, the caller would read back a corrupt value. Since
70 // we call forget, the caller must deallocate externally to prevent leaks.
71 std::mem::forget(conf);
72 return ((ptr as u64) << 32) | len as u64;
73}
74
75#[unsafe(no_mangle)]
76extern "C" fn gitrootAlloc(size: u32) -> *mut u8 {
77 // Allocate the amount of bytes needed.
78 let vec: Vec<MaybeUninit<u8>> = vec![MaybeUninit::uninit(); size as usize];
79 // into_raw leaks the memory to the caller.
80 Box::into_raw(vec.into_boxed_slice()) as *mut u8
81}
82
83#[unsafe(no_mangle)]
84extern "C" fn gitrootFree(ptr: u32, size: u32) {
85 unsafe {
86 let _ = Vec::from_raw_parts(ptr as *mut u8, 0, size as usize);
87 }
88}