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}