lgbm 0.0.6

Unofficial Rust bindings for LightGBM
Documentation
use crate::{Error, Result, to_result};
use std::{
    ffi::{CString, c_char},
    os::raw::c_int,
    path::Path,
    ptr::null_mut,
};

pub fn to_cstring(value: &str) -> Result<CString> {
    if let Ok(value) = CString::new(value) {
        Ok(value)
    } else {
        Err(convert_string_error())
    }
}

pub const fn bool_to_int(value: bool) -> c_int {
    if value { 1 } else { 0 }
}
pub const fn int_to_bool(value: c_int) -> bool {
    value != 0
}

pub fn path_to_cstring(path: &Path) -> Result<CString> {
    if let Some(s) = path.to_str() {
        return Ok(CString::new(s)?);
    }
    Err(convert_string_error())
}
pub fn get_strings(
    get: impl Fn(c_int, *mut c_int, usize, *mut usize, *mut *mut c_char) -> c_int,
) -> Result<Vec<String>> {
    let mut len = 0;
    let mut buffer_len = 0;
    to_result(get(0, &mut len, 0, &mut buffer_len, null_mut()))?;
    let mut buffers = vec![vec![0u8; buffer_len]; len as usize];
    let mut out_strs = buffers
        .iter_mut()
        .map(|x| x.as_mut_ptr() as *mut c_char)
        .collect::<Vec<_>>();
    let mut out_len = 0;
    let mut out_buffer_len = 0;
    to_result(get(
        len,
        &mut out_len,
        buffer_len,
        &mut out_buffer_len,
        out_strs.as_mut_ptr(),
    ))?;
    out_strs.truncate(out_len as usize);
    buffers.into_iter().map(chars_to_string).collect()
}
pub fn get_bytes(get: impl Fn(i64, *mut i64, *mut c_char) -> c_int) -> Result<Vec<u8>> {
    let mut buffer: Vec<u8> = Vec::new();
    loop {
        let mut out_len = 0;
        to_result(get(
            buffer.len() as i64,
            &mut out_len,
            buffer.as_mut_ptr() as *mut c_char,
        ))?;
        let out_len = out_len as usize;
        if out_len <= buffer.len() {
            buffer.truncate(out_len);
            return Ok(buffer);
        }
        buffer.resize(out_len, 0);
    }
}
pub fn get_cstring(get: impl Fn(i64, *mut i64, *mut c_char) -> c_int) -> Result<CString> {
    Ok(CString::from_vec_with_nul(get_bytes(get)?)?)
}

pub fn chars_to_string(mut chars: Vec<u8>) -> Result<String> {
    if let Some(index) = chars.iter().position(|&x| x == 0) {
        chars.truncate(index);
    }
    Ok(String::from_utf8(chars)?)
}

fn convert_string_error() -> Error {
    Error::from_message("failed to convert string")
}