use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
use core::ffi::c_int;
use myrmic_common::types::error::{ENOMEM, SUCCESS};
use crate::{ApiError, ApiResult};
mod c_functions {
use core::ffi::c_int;
#[link(wasm_import_module = "runtime")]
unsafe extern "C" {
pub(super) fn runtime_tags_len_host() -> i32;
pub(super) fn runtime_tags_host(buffer: *mut u8, length: c_int) -> i32;
pub(super) fn runtime_id_host(buffer: *mut u8, length: c_int) -> i32;
}
}
const RUNTIME_TAGS_MAX_ATTEMPTS: usize = 3;
const RUNTIME_ID_BUFFER_LEN: usize = 64;
#[allow(clippy::cast_sign_loss)]
pub fn runtime_tags() -> ApiResult<Vec<String>> {
for _ in 0..RUNTIME_TAGS_MAX_ATTEMPTS {
let len = unsafe { c_functions::runtime_tags_len_host() };
if len < 0 {
return Err(len.into());
}
let mut buf = vec![0u8; len as usize];
let status =
unsafe { c_functions::runtime_tags_host(buf.as_mut_ptr(), buf.len() as c_int) };
match status {
SUCCESS => {
return postcard::from_bytes(&buf)
.map_err(|_e| ApiError::Serde("deserializing runtime tags"));
}
ENOMEM => continue,
code => return Err(code.into()),
}
}
Err(ApiError::BufferTooSmall)
}
pub fn runtime_id() -> ApiResult<String> {
let mut buf = [0u8; RUNTIME_ID_BUFFER_LEN];
let status = unsafe { c_functions::runtime_id_host(buf.as_mut_ptr(), buf.len() as c_int) };
match status {
SUCCESS => {
postcard::from_bytes(&buf).map_err(|_e| ApiError::Serde("deserializing runtime id"))
}
code => Err(code.into()),
}
}