#![warn(unsafe_op_in_unsafe_fn)]
#![allow(non_camel_case_types)]
#![allow(clippy::missing_safety_doc)]
#![allow(unused_unsafe)]
use ffizz_passby::Value;
use libc::c_char;
use std::ffi::CStr;
use uuid::Uuid;
pub const UUID_STRING_BYTES: usize = 36;
#[derive(Clone, Copy)]
#[repr(C)]
pub struct uuid_t([u8; 16]);
type UuidValue = Value<Uuid, uuid_t>;
impl Into<Uuid> for uuid_t {
fn into(self) -> Uuid {
uuid::Uuid::from_bytes(self.0)
}
}
impl From<Uuid> for uuid_t {
fn from(rval: Uuid) -> uuid_t {
uuid_t(*rval.as_bytes())
}
}
#[no_mangle]
pub unsafe extern "C" fn uuid_new_v4() -> uuid_t {
unsafe { UuidValue::return_val(uuid::Uuid::new_v4()) }
}
#[no_mangle]
pub unsafe extern "C" fn uuid_nil() -> uuid_t {
unsafe { UuidValue::return_val(uuid::Uuid::nil()) }
}
#[no_mangle]
pub unsafe extern "C" fn uuid_version(uuid: uuid_t) -> usize {
let uuid = unsafe { UuidValue::take(uuid) };
uuid.get_version_num()
}
#[no_mangle]
pub unsafe extern "C" fn uuid_to_buf(tcuuid: uuid_t, buf: *mut c_char) {
debug_assert!(!buf.is_null());
let buf: &mut [u8] =
unsafe { std::slice::from_raw_parts_mut(buf as *mut u8, UUID_STRING_BYTES) };
let uuid = unsafe { UuidValue::take(tcuuid) };
uuid.as_hyphenated().encode_lower(buf);
}
#[no_mangle]
pub unsafe extern "C" fn uuid_from_str(s: *const c_char, uuid_out: *mut uuid_t) -> bool {
debug_assert!(!s.is_null());
debug_assert!(!uuid_out.is_null());
let s = unsafe { CStr::from_ptr(s) };
if let Ok(s) = s.to_str() {
if let Ok(u) = uuid::Uuid::parse_str(s) {
unsafe { UuidValue::to_out_param(u, uuid_out) };
return true;
}
}
false
}
fn main() {
let u = unsafe { uuid_new_v4() };
assert_eq!(unsafe { uuid_version(u) }, 4);
let u = unsafe { uuid_nil() };
assert_eq!(unsafe { uuid_version(u) }, 0);
let mut buf = [0u8; UUID_STRING_BYTES];
unsafe { uuid_to_buf(u, buf.as_mut_ptr() as *mut c_char) };
assert_eq!(
std::str::from_utf8(&buf[..]).expect("invalid utf-8"),
"00000000-0000-0000-0000-000000000000"
);
let mut u = unsafe { uuid_nil() };
assert!(unsafe {
uuid_from_str(
"d9c5d004-1bf4-11ed-861d-0242ac120002\0".as_ptr() as *const c_char,
&mut u as *mut uuid_t,
)
});
assert_eq!(unsafe { uuid_version(u) }, 1);
}