use alloc::string::String;
use alloc::vec::Vec;
use myrmic_common::db::{
DeleteRequest, GetRequest, GetResponse, PrefixRequest, PrefixResponse, PutRequest, Scope,
};
use crate::error::ErrorCode;
use crate::{ApiError, ApiResult};
mod c_functions {
use core::ffi::c_int;
#[link(wasm_import_module = "db")]
unsafe extern "C" {
pub(super) fn key_put(buffer: *const u8, length: c_int) -> c_int;
pub(super) fn key_get(
buffer_req: *const u8,
len_req: c_int,
buffer_rsp: *mut u8,
len_rsp: c_int,
) -> c_int;
pub(super) fn key_delete(buffer_req: *const u8, len_req: c_int) -> c_int;
pub(super) fn key_prefix(
buffer_req: *const u8,
len_req: c_int,
buffer_rsp: *mut u8,
len_rsp: c_int,
) -> c_int;
}
}
pub fn key_put(scope: Scope, key: String, value: Vec<u8>, buffer: &mut [u8]) -> ApiResult<()> {
let payload = PutRequest { scope, key, value };
let len = postcard::to_slice(&payload, buffer)
.map_err(|_e| ApiError::Serde("serializing put request"))?
.len();
unsafe { c_functions::key_put(buffer.as_ptr(), len as i32) }.to_result()
}
pub fn key_get(
scope: Scope,
key: String,
request_buffer: &mut [u8],
response_buffer: &mut [u8],
) -> ApiResult<Option<Vec<u8>>> {
let request = GetRequest { scope, key };
let payload_len = postcard::to_slice(&request, request_buffer)
.map_err(|_e| ApiError::Serde("serializing get request"))?
.len();
unsafe {
c_functions::key_get(
request_buffer.as_ptr(),
payload_len as i32,
response_buffer.as_mut_ptr(),
response_buffer.len() as i32,
)
}
.to_result()?;
let response = postcard::from_bytes::<GetResponse>(response_buffer)
.map_err(|_e| ApiError::Serde("deserializing get response"))?;
Ok(response.payload)
}
pub fn key_delete(scope: Scope, key: String, buffer: &mut [u8]) -> ApiResult<()> {
let delete_request = DeleteRequest { scope, key };
let payload_len = postcard::to_slice(&delete_request, buffer)
.map_err(|_e| ApiError::Serde("serializing delete request"))?
.len();
unsafe { c_functions::key_delete(buffer.as_ptr(), payload_len as i32) }.to_result()
}
pub fn key_prefix(
scope: Scope,
prefix: String,
request_buffer: &mut [u8],
response_buffer: &mut [u8],
) -> ApiResult<Vec<String>> {
let request = PrefixRequest { scope, prefix };
let payload_len = postcard::to_slice(&request, request_buffer)
.map_err(|_e| ApiError::Serde("serializing prefix request"))?
.len();
unsafe {
c_functions::key_prefix(
request_buffer.as_ptr(),
payload_len as i32,
response_buffer.as_mut_ptr(),
response_buffer.len() as i32,
)
}
.to_result()?;
let response = postcard::from_bytes::<PrefixResponse>(response_buffer)
.map_err(|_e| ApiError::Serde("deserializing prefix response"))?;
Ok(response.keys)
}