1use libc::{c_char, c_int};
2use std::ffi::{CStr, CString};
3
4#[link(name = "gnparser")]
5extern "C" {
6 fn ParseToString(name: *const c_char, f: *const c_char, details: c_int, cultivars: c_int, diaereses: c_int) -> *mut c_char;
7 fn FreeMemory(p: *mut c_char);
8 fn ParseAryToString(in_: *const *const c_char, length: c_int, f: *const c_char, details: c_int, cultivars: c_int, diaereses: c_int) -> *mut c_char;
9}
10
11pub fn parse_to_string(name: &str, format: &str, details: bool, cultivars: bool, diaereses: bool) -> Result<String, String> {
12 let name_cstr = CString::new(name).map_err(|e| e.to_string())?;
13 let format_cstr = CString::new(format).map_err(|e| e.to_string())?;
14 let details = if details { 1 } else { 0 };
15 let cultivars = if cultivars { 1 } else { 0 };
16 let diaereses = if diaereses { 1 } else { 0 };
17
18 unsafe {
19 let result_ptr = ParseToString(name_cstr.as_ptr(), format_cstr.as_ptr(), details, cultivars, diaereses);
20 if result_ptr.is_null() {
21 return Err("Failed to parse name".into());
22 }
23 let result = CStr::from_ptr(result_ptr).to_string_lossy().into_owned();
24 FreeMemory(result_ptr);
25 Ok(result)
26 }
27}
28
29pub fn parse_ary_to_string(names: &[&str], format: &str, details: bool, cultivars: bool, diaereses: bool) -> Result<String, String> {
30 let format_cstr = CString::new(format).map_err(|e| e.to_string())?;
31 let details = if details { 1 } else { 0 };
32 let cultivars = if cultivars { 1 } else { 0 };
33 let diaereses = if diaereses { 1 } else { 0 };
34
35 let cstrings: Vec<CString> = names.iter().map(|&s| CString::new(s).unwrap()).collect();
36 let ptrs: Vec<*const c_char> = cstrings.iter().map(|s| s.as_ptr()).collect();
37
38 unsafe {
39 let result_ptr = ParseAryToString(ptrs.as_ptr(), names.len() as c_int, format_cstr.as_ptr(), details, cultivars, diaereses);
40 if result_ptr.is_null() {
41 return Err("Failed to parse names array".into());
42 }
43 let result = CStr::from_ptr(result_ptr).to_string_lossy().into_owned();
44 FreeMemory(result_ptr);
45 Ok(result)
46 }
47}