1
#![allow(warnings)]
2
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
3

            
4
#[cfg(test)]
5
mod 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
1
    pub extern "C" fn hello_from_rust() -> bool {
17
1
        unsafe {
18
1
            X_VAL = printMatrix_getValue(0) as _;
19
1
            Y_VAL = printMatrix_getValue(1) as _;
20
1
            Z_VAL = printMatrix_getValue(2) as _;
21
1
            return true;
22
1
        }
23
1
    }
24

            
25
    #[test]
26
1
    fn xyz_raw() {
27
1
        // A simple constraints model, manually written using FFI functions.
28
1
        // Testing to see if it does not segfault.
29
1
        // Results can be manually inspected in the outputted minion logs.
30
1
        unsafe {
31
1
            // See https://rust-lang.github.io/rust-bindgen/cpp.html
32
1
            let options = searchOptions_new();
33
1
            let args = searchMethod_new();
34
1
            let instance = instance_new();
35
1

            
36
1
            let x_str = CString::new("x").expect("bad x");
37
1
            let y_str = CString::new("y").expect("bad y");
38
1
            let z_str = CString::new("z").expect("bad z");
39
1

            
40
1
            newVar_ffi(instance, x_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 3);
41
1
            newVar_ffi(instance, y_str.as_ptr() as _, VariableType_VAR_BOUND, 2, 4);
42
1
            newVar_ffi(instance, z_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 5);
43
1

            
44
1
            let x = getVarByName(instance, x_str.as_ptr() as _);
45
1
            let y = getVarByName(instance, y_str.as_ptr() as _);
46
1
            let z = getVarByName(instance, z_str.as_ptr() as _);
47
1

            
48
1
            // PRINT
49
1
            printMatrix_addVar(instance, x);
50
1
            printMatrix_addVar(instance, y);
51
1
            printMatrix_addVar(instance, z);
52
1

            
53
1
            // VARORDER
54
1
            let search_vars = vec_var_new();
55
1
            vec_var_push_back(search_vars as _, x);
56
1
            vec_var_push_back(search_vars as _, y);
57
1
            vec_var_push_back(search_vars as _, z);
58
1
            let search_order = searchOrder_new(search_vars as _, VarOrderEnum_ORDER_STATIC, false);
59
1
            instance_addSearchOrder(instance, search_order);
60
1

            
61
1
            // CONSTRAINTS
62
1
            let leq = constraint_new(ConstraintType_CT_LEQSUM);
63
1
            let geq = constraint_new(ConstraintType_CT_GEQSUM);
64
1
            let ineq = constraint_new(ConstraintType_CT_INEQ);
65
1

            
66
1
            let rhs_vars = vec_var_new();
67
1
            vec_var_push_back(rhs_vars, constantAsVar(4));
68
1

            
69
1
            // leq / geq : [var] [var]
70
1
            constraint_addList(leq, search_vars as _);
71
1
            constraint_addList(leq, rhs_vars as _);
72
1

            
73
1
            constraint_addList(geq, search_vars as _);
74
1
            constraint_addList(geq, rhs_vars as _);
75
1

            
76
1
            // ineq: [var] [var] [const]
77
1
            let x_vec = vec_var_new();
78
1
            vec_var_push_back(x_vec, x);
79
1

            
80
1
            let y_vec = vec_var_new();
81
1
            vec_var_push_back(y_vec, y);
82
1

            
83
1
            let const_vec = vec_int_new();
84
1
            vec_int_push_back(const_vec, -1);
85
1

            
86
1
            constraint_addList(ineq, x_vec as _);
87
1
            constraint_addList(ineq, y_vec as _);
88
1
            constraint_addConstantList(ineq, const_vec as _);
89
1

            
90
1
            instance_addConstraint(instance, leq);
91
1
            instance_addConstraint(instance, geq);
92
1
            instance_addConstraint(instance, ineq);
93
1

            
94
1
            let res = runMinion(options, args, instance, Some(hello_from_rust));
95
1

            
96
1
            // does it get this far?
97
1
            assert_eq!(res, 0);
98

            
99
            // test if solutions are correct
100
1
            assert_eq!(X_VAL, 1);
101
1
            assert_eq!(Y_VAL, 2);
102
1
            assert_eq!(Z_VAL, 1);
103
        }
104
1
    }
105
}