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::model::{Call, CallRes, Commit, ConfPlugin, File, PluginSdkType, Report};
  7use crate::ptr::{ptr_to_string, string_to_ptr};
  8use std::collections::HashMap;
  9use std::mem::MaybeUninit;
 10
 11#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "init"))]
 12pub fn init(
 13    repo_name_ptr: u32,
 14    repo_name_size: u32,
 15    conf_has_changed_ptr: u32,
 16    conf_has_changed_size: u32,
 17    conf_ptr: u32,
 18    conf_size: u32,
 19) {
 20    let repo_name = ptr_to_string(repo_name_ptr, repo_name_size);
 21    let conf_has_changed = ptr_to_string(conf_has_changed_ptr, conf_has_changed_size) == "true";
 22    let conf = ptr_to_string(conf_ptr, conf_size);
 23    with_plugin(|plugin| plugin.init(repo_name, conf_has_changed, conf));
 24}
 25
 26#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "startCommit"))]
 27pub fn start_commit(json: &str) {
 28    let commit: Commit = serde_json::from_str(json).expect("JSON was not well-formatted");
 29    with_plugin(|plugin| plugin.start_commit(commit));
 30}
 31
 32#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "addFile"))]
 33pub fn add_file(json: &str) {
 34    let file: File = serde_json::from_str(json).expect("JSON was not well-formatted");
 35    with_plugin(|plugin| plugin.add_file(file));
 36}
 37
 38#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "modFile"))]
 39pub fn mod_file(json: &str) {
 40    let file: File = serde_json::from_str(json).expect("JSON was not well-formatted");
 41    with_plugin(|plugin| plugin.mod_file(file));
 42}
 43
 44#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "delFile"))]
 45pub fn del_file(json: &str) {
 46    let file: File = serde_json::from_str(json).expect("JSON was not well-formatted");
 47    with_plugin(|plugin| plugin.del_file(file));
 48}
 49
 50#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "endCommit"))]
 51pub fn end_commit(json: &str) {
 52    let commit: Commit = serde_json::from_str(json).expect("JSON was not well-formatted");
 53    with_plugin(|plugin| plugin.end_commit(commit));
 54}
 55
 56#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "finish"))]
 57pub fn finish() {
 58    with_plugin(|plugin| plugin.finish());
 59}
 60
 61#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "report"))]
 62pub fn report(json: &str) {
 63    let report: Report = serde_json::from_str(json).expect("JSON was not well-formatted");
 64    with_plugin_reporter(|plugin| plugin.report(report));
 65}
 66
 67#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "call"))]
 68pub fn call(json: &str) -> u64 {
 69    let c: Call = serde_json::from_str(json).expect("JSON was not well-formatted");
 70    let call_res = match get().call_internal_func(c) {
 71        Ok(map) => CallRes {
 72            res: map,
 73            err: String::new(), // Pas d'erreur, on met une chaรฎne vide
 74        },
 75        Err(e) => CallRes {
 76            res: HashMap::new(), // Erreur, on renvoie une map vide
 77            err: e,
 78        },
 79    };
 80    let call_res_string = serde_json::to_string(&call_res).unwrap();
 81    let (ptr, len) = string_to_ptr(&call_res_string);
 82    // Note: This changes ownership of the pointer to the external caller. If
 83    // we didn't call forget, the caller would read back a corrupt value. Since
 84    // we call forget, the caller must deallocate externally to prevent leaks.
 85    std::mem::forget(call_res_string);
 86    ((ptr as u64) << 32) | len as u64
 87}
 88
 89/// # Safety
 90///
 91/// Called by host
 92#[cfg_attr(all(target_arch = "wasm32"), unsafe(export_name = "pluginConf"))]
 93pub unsafe extern "C" fn plugin_conf() -> u64 {
 94    let conf_plugin = ConfPlugin {
 95        default_run: get().run.clone(),
 96        sdk_version: String::from("0.5.0"),
 97        sdk_type: PluginSdkType::Tinygo,
 98    };
 99    let conf = serde_json::to_string(&conf_plugin).unwrap();
100    let (ptr, len) = string_to_ptr(&conf);
101    // Note: This changes ownership of the pointer to the external caller. If
102    // we didn't call forget, the caller would read back a corrupt value. Since
103    // we call forget, the caller must deallocate externally to prevent leaks.
104    std::mem::forget(conf);
105    ((ptr as u64) << 32) | len as u64
106}
107
108#[unsafe(no_mangle)]
109extern "C" fn gitrootAlloc(size: u32) -> *mut u8 {
110    // Allocate the amount of bytes needed.
111    let vec: Vec<MaybeUninit<u8>> = vec![MaybeUninit::uninit(); size as usize];
112    // into_raw leaks the memory to the caller.
113    Box::into_raw(vec.into_boxed_slice()) as *mut u8
114}
115
116#[unsafe(no_mangle)]
117extern "C" fn gitrootFree(ptr: u32, size: u32) {
118    unsafe {
119        let _ = Vec::from_raw_parts(ptr as *mut u8, 0, size as usize);
120    }
121}