1use std::ffi::{c_char, CString};
4
5pub(crate) fn take_ownership_string(s: CString) -> *mut c_char {
7 s.into_raw()
8}
9
10#[no_mangle]
16pub unsafe extern "C" fn laminar_string_free(s: *mut c_char) {
17 if !s.is_null() {
18 drop(unsafe { CString::from_raw(s) });
19 }
20}
21
22#[no_mangle]
28pub extern "C" fn laminar_version() -> *const c_char {
29 static VERSION: &[u8] = concat!(env!("CARGO_PKG_VERSION"), "\0").as_bytes();
30 VERSION.as_ptr().cast()
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use std::ffi::CStr;
37
38 #[test]
39 fn test_string_free_null() {
40 unsafe {
43 laminar_string_free(std::ptr::null_mut());
44 }
45 }
46
47 #[test]
48 fn test_string_round_trip() {
49 let original = "Hello, FFI!";
50 let c_string = CString::new(original).unwrap();
51 let ptr = take_ownership_string(c_string);
52
53 let retrieved = unsafe { CStr::from_ptr(ptr).to_str().unwrap() };
55 assert_eq!(retrieved, original);
56
57 unsafe { laminar_string_free(ptr) };
59 }
60
61 #[test]
62 fn test_version() {
63 let ptr = laminar_version();
64 assert!(!ptr.is_null());
65
66 let version = unsafe { CStr::from_ptr(ptr).to_str().unwrap() };
68 assert!(!version.is_empty());
69 assert!(version.chars().any(|c| c.is_ascii_digit()));
71 }
72}