nautilus_core/ffi/
uuid.rs1use std::{
17 collections::hash_map::DefaultHasher,
18 ffi::{c_char, CStr},
19 hash::{Hash, Hasher},
20};
21
22use crate::UUID4;
23
24#[no_mangle]
25pub extern "C" fn uuid4_new() -> UUID4 {
26 UUID4::new()
27}
28
29#[no_mangle]
40pub unsafe extern "C" fn uuid4_from_cstr(ptr: *const c_char) -> UUID4 {
41 assert!(!ptr.is_null(), "`ptr` was NULL");
42 let cstr = unsafe { CStr::from_ptr(ptr) };
43 let value = cstr.to_str().expect("Failed to convert C string to UTF-8");
44 UUID4::from(value)
45}
46
47#[no_mangle]
48pub extern "C" fn uuid4_to_cstr(uuid: &UUID4) -> *const c_char {
49 uuid.to_cstr().as_ptr()
50}
51
52#[no_mangle]
53pub extern "C" fn uuid4_eq(lhs: &UUID4, rhs: &UUID4) -> u8 {
54 u8::from(lhs == rhs)
55}
56
57#[no_mangle]
58pub extern "C" fn uuid4_hash(uuid: &UUID4) -> u64 {
59 let mut h = DefaultHasher::new();
60 uuid.hash(&mut h);
61 h.finish()
62}
63
64#[cfg(test)]
68mod tests {
69 use std::ffi::CString;
70
71 use rstest::*;
72 use uuid::{self, Uuid};
73
74 use super::*;
75
76 #[rstest]
77 fn test_new() {
78 let uuid = uuid4_new();
79 let uuid_string = uuid.to_string();
80 let uuid_parsed = Uuid::parse_str(&uuid_string).expect("Uuid::parse_str failed");
81 assert_eq!(uuid_parsed.get_version().unwrap(), uuid::Version::Random);
82 }
83
84 #[rstest]
85 fn test_from_cstr() {
86 let uuid_string = "2d89666b-1a1e-4a75-b193-4eb3b454c757";
87 let uuid_cstring = CString::new(uuid_string).expect("CString::new failed");
88 let uuid_ptr = uuid_cstring.as_ptr();
89 let uuid = unsafe { uuid4_from_cstr(uuid_ptr) };
90 assert_eq!(uuid_string, uuid.to_string());
91 }
92
93 #[rstest]
94 fn test_to_cstr() {
95 let uuid_string = "2d89666b-1a1e-4a75-b193-4eb3b454c757";
96 let uuid = UUID4::from(uuid_string);
97 let uuid_ptr = uuid4_to_cstr(&uuid);
98 let uuid_cstr = unsafe { CStr::from_ptr(uuid_ptr) };
99 let uuid_result_string = uuid_cstr.to_str().expect("CStr::to_str failed").to_string();
100 assert_eq!(uuid_string, uuid_result_string);
101 }
102
103 #[rstest]
104 fn test_eq() {
105 let uuid1 = UUID4::from("2d89666b-1a1e-4a75-b193-4eb3b454c757");
106 let uuid2 = UUID4::from("2d89666b-1a1e-4a75-b193-4eb3b454c757");
107 let uuid3 = UUID4::from("2d89666b-1a1e-4a75-b193-4eb3b454c758");
108 assert_eq!(uuid4_eq(&uuid1, &uuid2), 1);
109 assert_eq!(uuid4_eq(&uuid1, &uuid3), 0);
110 }
111
112 #[rstest]
113 fn test_hash() {
114 let uuid1 = UUID4::from("2d89666b-1a1e-4a75-b193-4eb3b454c757");
115 let uuid2 = UUID4::from("2d89666b-1a1e-4a75-b193-4eb3b454c757");
116 let uuid3 = UUID4::from("2d89666b-1a1e-4a75-b193-4eb3b454c758");
117 assert_eq!(uuid4_hash(&uuid1), uuid4_hash(&uuid2));
118 assert_ne!(uuid4_hash(&uuid1), uuid4_hash(&uuid3));
119 }
120}