1#![warn(unsafe_op_in_unsafe_fn)]
2#![allow(non_camel_case_types)]
3#![allow(clippy::missing_safety_doc)]
4#![allow(unused_unsafe)]
5
6use ffizz_passby::Value;
7use libc::c_char;
8use std::ffi::CStr;
9use uuid::Uuid;
10
11pub const UUID_STRING_BYTES: usize = 36;
13
14#[derive(Clone, Copy)]
16#[repr(C)]
17pub struct uuid_t([u8; 16]);
18
19type UuidValue = Value<Uuid, uuid_t>;
20
21impl Into<Uuid> for uuid_t {
22 fn into(self) -> Uuid {
23 uuid::Uuid::from_bytes(self.0)
26 }
27}
28impl From<Uuid> for uuid_t {
29 fn from(rval: Uuid) -> uuid_t {
30 uuid_t(*rval.as_bytes())
31 }
32}
33
34#[no_mangle]
36pub unsafe extern "C" fn uuid_new_v4() -> uuid_t {
37 unsafe { UuidValue::return_val(uuid::Uuid::new_v4()) }
40}
41
42#[no_mangle]
44pub unsafe extern "C" fn uuid_nil() -> uuid_t {
45 unsafe { UuidValue::return_val(uuid::Uuid::nil()) }
48}
49
50#[no_mangle]
52pub unsafe extern "C" fn uuid_version(uuid: uuid_t) -> usize {
53 let uuid = unsafe { UuidValue::take(uuid) };
56 uuid.get_version_num()
57}
58
59#[no_mangle]
66pub unsafe extern "C" fn uuid_to_buf(tcuuid: uuid_t, buf: *mut c_char) {
67 debug_assert!(!buf.is_null());
68 let buf: &mut [u8] =
75 unsafe { std::slice::from_raw_parts_mut(buf as *mut u8, UUID_STRING_BYTES) };
76 let uuid = unsafe { UuidValue::take(tcuuid) };
79 uuid.as_hyphenated().encode_lower(buf);
80}
81
82#[no_mangle]
91pub unsafe extern "C" fn uuid_from_str(s: *const c_char, uuid_out: *mut uuid_t) -> bool {
92 debug_assert!(!s.is_null());
93 debug_assert!(!uuid_out.is_null());
94 let s = unsafe { CStr::from_ptr(s) };
97 if let Ok(s) = s.to_str() {
98 if let Ok(u) = uuid::Uuid::parse_str(s) {
99 unsafe { UuidValue::to_out_param(u, uuid_out) };
103 return true;
104 }
105 }
106 false
107}
108
109fn main() {
110 let u = unsafe { uuid_new_v4() };
111 assert_eq!(unsafe { uuid_version(u) }, 4);
112
113 let u = unsafe { uuid_nil() };
114 assert_eq!(unsafe { uuid_version(u) }, 0);
115
116 let mut buf = [0u8; UUID_STRING_BYTES];
117 unsafe { uuid_to_buf(u, buf.as_mut_ptr() as *mut c_char) };
118 assert_eq!(
119 std::str::from_utf8(&buf[..]).expect("invalid utf-8"),
120 "00000000-0000-0000-0000-000000000000"
121 );
122
123 let mut u = unsafe { uuid_nil() };
124 assert!(unsafe {
125 uuid_from_str(
126 "d9c5d004-1bf4-11ed-861d-0242ac120002\0".as_ptr() as *const c_char,
128 &mut u as *mut uuid_t,
129 )
130 });
131 assert_eq!(unsafe { uuid_version(u) }, 1);
132}