minion_sys/
ffi.rs

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