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