haqumei 0.2.0

Haqumei is a Japanese Grapheme-to-Phoneme (G2P) library implemented in Rust.
Documentation
use std::ffi::{CString, c_char};

use crate::{errors::HaqumeiError, ffi};

#[derive(Debug)]
pub(crate) struct MecabModel {
    pub(crate) ptr: *mut ffi::mecab_model_t,
}

impl MecabModel {
    pub fn new(dict_dir: &str, user_dict: Option<&str>) -> Result<Self, HaqumeiError> {
        let mut argv: Vec<*mut c_char> = Vec::new();

        let arg0 = CString::new("mecab").unwrap();
        let arg1 = CString::new("-d").unwrap();
        let arg2 = CString::new(dict_dir).map_err(|_| HaqumeiError::MecabLoadError)?;
        let arg3 = CString::new("-u").unwrap();

        let user_dic_c: Option<CString> = user_dict.map(CString::new).transpose()?;

        argv.push(arg0.as_ptr() as *mut _);
        argv.push(arg1.as_ptr() as *mut _);
        argv.push(arg2.as_ptr() as *mut _);

        if let Some(udic) = &user_dic_c {
            argv.push(arg3.as_ptr() as *mut _);
            argv.push(udic.as_ptr() as *mut _);
        }

        let model_ptr = unsafe { ffi::mecab_model_new(argv.len() as i32, argv.as_mut_ptr()) };

        if model_ptr.is_null() {
            Err(HaqumeiError::MecabLoadError)
        } else {
            Ok(Self { ptr: model_ptr })
        }
    }

    #[allow(unused)]
    pub(crate) fn new_uninitialized() -> Self {
        Self {
            ptr: std::ptr::null_mut(),
        }
    }

    pub(crate) fn is_initialized(&self) -> bool {
        !self.ptr.is_null()
    }
}

impl Drop for MecabModel {
    fn drop(&mut self) {
        unsafe {
            ffi::mecab_model_destroy(self.ptr);
        }
    }
}