use std::ffi::c_char;
use std::{
ptr,
slice,
};
use libc::size_t;
use super::error::Error;
use crate::ffi::util;
use crate::ffi::util::cstr_from_ptr;
use crate::Key;
mod private;
mod public;
#[track_caller]
#[inline]
unsafe fn parse_str<T, F>(s: *const c_char, key: *mut *mut T, f: F) -> Error
where
F: FnOnce(&str) -> crate::Result<T>,
{
assert!(!key.is_null());
let s = unsafe { cstr_from_ptr(s) };
let parsed = ffi_try!(f(&s));
unsafe { ptr::write(key, Box::into_raw(Box::new(parsed))) }
Error::Ok
}
#[track_caller]
#[inline]
unsafe fn parse_bytes<T, F>(bytes: *const u8, bytes_size: size_t, key: *mut *mut T, f: F) -> Error
where
F: FnOnce(&[u8]) -> crate::Result<T>,
{
assert!(!bytes.is_null());
assert!(!key.is_null());
let bytes = unsafe { slice::from_raw_parts(bytes, bytes_size) };
let parsed = ffi_try!(f(bytes));
unsafe { ptr::write(key, Box::into_raw(Box::new(parsed))) }
Error::Ok
}
#[track_caller]
#[inline]
unsafe fn to_bytes<T, F>(key: *const T, buf: *mut *mut u8, f: F) -> size_t
where
F: FnOnce(&T) -> Vec<u8>,
{
assert!(!buf.is_null());
let key = unsafe { key.as_ref().unwrap() };
let bytes = f(key).into_boxed_slice();
let bytes = Box::leak(bytes);
let len = bytes.len();
let bytes = bytes.as_mut_ptr();
unsafe {
ptr::write(buf, bytes);
}
len
}
#[no_mangle]
pub unsafe extern "C" fn hedera_key_to_bytes(
s: *const c_char,
buf: *mut *mut u8,
buf_size: *mut libc::size_t,
) -> Error {
unsafe { util::json_to_bytes(s, buf, buf_size, Key::to_bytes) }
}