choco-solver 0.1.0

Safe interface for the Choco Solver library DLL generated by GraalVM Native Image.
Documentation
mod intvar;
pub use intvar::*;
use std::fmt::Display;

use crate::utils::{HandleT, ModelObject};
use crate::{CHOCO_BACKEND, CHOCO_LIB, Sealed};

/// # Safety
/// - This trait assumes that the implementor provides a valid handle to a variable in the backend
/// - This trait assumes that the Choco backend is initialized when its methods are called.
#[allow(private_bounds)]
#[doc(hidden)]
pub unsafe trait Variable<'model>: ModelObject<'model> + Sealed {
    fn name(&self) -> String {
        CHOCO_BACKEND.with(|backend|
        // Safety:
        // - Guaranteed by caller as in trait safety comment
        unsafe {
            let name_ptr = CHOCO_LIB.Java_org_chocosolver_capi_VariableApi_getName(backend.thread,self.get_raw_handle());
            // Java backend assigned autogenerated variables name if a name is not assigned
            // at creation, so name_ptr should never be null.
            debug_assert!(!name_ptr.is_null(), "Variable name pointer is null");

            let c_str = std::ffi::CStr::from_ptr(name_ptr);
            c_str.to_string_lossy().into_owned()
        })
    }
    fn is_instantiated(&self) -> bool {
        CHOCO_BACKEND.with(|backend|
        // Safety:
        // - Guaranteed by caller as in trait safety comment
        unsafe {
            let result = CHOCO_LIB.Java_org_chocosolver_capi_VariableApi_isInstantiated(backend.thread, self.get_raw_handle());
            result != 0
        })
    }
    fn is_view(&self) -> bool {
        CHOCO_BACKEND.with(|backend|
        // Safety:
        // - Guaranteed by caller as in trait safety comment
        unsafe {
            let result = CHOCO_LIB.Java_org_chocosolver_capi_VariableApi_isView(backend.thread, self.get_raw_handle());
            result != 0
        })
    }
}

#[cfg(test)]
mod tests {

    use crate::*;
    #[test]
    fn test_variable_name() {
        let model = Model::new(Some("TestModel"));
        let var = model.int_var(0, Some("TestVar"));
        assert_eq!(var.name(), "TestVar");
    }
    #[test]
    fn test_is_view() {
        let model = Model::new(Some("TestModel"));
        let var = model.int_var(0, Some("TestVar"));
        assert!(!var.is_view());
    }
}