minion_rs/
ffi.rs

1#![allow(warnings)]
2include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
3
4#[cfg(test)]
5mod tests {
6    use std::ffi::CString;
7
8    use super::*;
9
10    // solutions
11    static mut X_VAL: i32 = 0;
12    static mut Y_VAL: i32 = 0;
13    static mut Z_VAL: i32 = 0;
14
15    #[no_mangle]
16    pub extern "C" fn hello_from_rust() -> bool {
17        unsafe {
18            X_VAL = printMatrix_getValue(0) as _;
19            Y_VAL = printMatrix_getValue(1) as _;
20            Z_VAL = printMatrix_getValue(2) as _;
21            return true;
22        }
23    }
24
25    #[test]
26    fn xyz_raw() {
27        // A simple constraints model, manually written using FFI functions.
28        // Testing to see if it does not segfault.
29        // Results can be manually inspected in the outputted minion logs.
30        unsafe {
31            // See https://rust-lang.github.io/rust-bindgen/cpp.html
32            let options = searchOptions_new();
33            let args = searchMethod_new();
34            let instance = instance_new();
35
36            let x_str = CString::new("x").expect("bad x");
37            let y_str = CString::new("y").expect("bad y");
38            let z_str = CString::new("z").expect("bad z");
39
40            newVar_ffi(instance, x_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 3);
41            newVar_ffi(instance, y_str.as_ptr() as _, VariableType_VAR_BOUND, 2, 4);
42            newVar_ffi(instance, z_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 5);
43
44            let x = getVarByName(instance, x_str.as_ptr() as _);
45            let y = getVarByName(instance, y_str.as_ptr() as _);
46            let z = getVarByName(instance, z_str.as_ptr() as _);
47
48            // PRINT
49            printMatrix_addVar(instance, x);
50            printMatrix_addVar(instance, y);
51            printMatrix_addVar(instance, z);
52
53            // VARORDER
54            let search_vars = vec_var_new();
55            vec_var_push_back(search_vars as _, x);
56            vec_var_push_back(search_vars as _, y);
57            vec_var_push_back(search_vars as _, z);
58            let search_order = searchOrder_new(search_vars as _, VarOrderEnum_ORDER_STATIC, false);
59            instance_addSearchOrder(instance, search_order);
60
61            // CONSTRAINTS
62            let leq = constraint_new(ConstraintType_CT_LEQSUM);
63            let geq = constraint_new(ConstraintType_CT_GEQSUM);
64            let ineq = constraint_new(ConstraintType_CT_INEQ);
65
66            let rhs_vars = vec_var_new();
67            vec_var_push_back(rhs_vars, constantAsVar(4));
68
69            // leq / geq : [var] [var]
70            constraint_addList(leq, search_vars as _);
71            constraint_addList(leq, rhs_vars as _);
72
73            constraint_addList(geq, search_vars as _);
74            constraint_addList(geq, rhs_vars as _);
75
76            // ineq: [var] [var] [const]
77            let x_vec = vec_var_new();
78            vec_var_push_back(x_vec, x);
79
80            let y_vec = vec_var_new();
81            vec_var_push_back(y_vec, y);
82
83            let const_vec = vec_int_new();
84            vec_int_push_back(const_vec, -1);
85
86            constraint_addList(ineq, x_vec as _);
87            constraint_addList(ineq, y_vec as _);
88            constraint_addConstantList(ineq, const_vec as _);
89
90            instance_addConstraint(instance, leq);
91            instance_addConstraint(instance, geq);
92            instance_addConstraint(instance, ineq);
93
94            let res = runMinion(options, args, instance, Some(hello_from_rust));
95
96            // does it get this far?
97            assert_eq!(res, 0);
98
99            // test if solutions are correct
100            assert_eq!(X_VAL, 1);
101            assert_eq!(Y_VAL, 2);
102            assert_eq!(Z_VAL, 1);
103        }
104    }
105}