gnparser/
lib.rs

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}