use std::{
ffi::{c_char, CStr, CString},
ptr::{null, null_mut},
};
use crate::{error::check_err, ffi};
pub struct GRBenv {
inner: *mut ffi::GRBenv,
}
impl GRBenv {
pub fn inner(&self) -> *mut ffi::GRBenv {
self.inner
}
pub fn new(empty: bool, logfilename: Option<&str>) -> Result<GRBenv, String> {
let mut env_ptr = null_mut();
let logfilename_ptr = match logfilename.map(|s| CString::new(s)) {
Some(Ok(cstr)) => cstr.as_ptr(),
Some(Err(_)) => return Err("Failed to convert logfilename to CString".to_string()),
None => null(),
};
let error = if empty {
unsafe { ffi::GRBemptyenv(&mut env_ptr) }
} else {
unsafe { ffi::GRBloadenv(&mut env_ptr, logfilename_ptr) }
};
let env = GRBenv { inner: env_ptr };
env.get_error(error).unwrap();
Ok(env)
}
pub fn start(&mut self) -> () {
unsafe {
ffi::GRBstartenv(self.inner);
}
}
pub fn get_error(&self, error_code: i32) -> Result<(), String> {
match check_err(error_code) {
Err(e) => unsafe {
Err(format!(
"ERROR CODE {}: {}",
e,
CStr::from_ptr(ffi::GRBgeterrormsg(self.inner()) as *mut c_char)
.to_string_lossy()
))
},
Ok(_o) => Ok(()),
}
}
}
impl Default for GRBenv {
fn default() -> Self {
GRBenv::new(false, None).expect("Failed to create default GRBenv")
}
}
impl Drop for GRBenv {
fn drop(&mut self) {
unsafe {
ffi::GRBfreeenv(self.inner);
}
}
}