Skip to main content

library_tests/
test_native_args.rs

1use std::ffi::CString;
2
3use wolfram_library_link::{
4    self as wll,
5    sys::{mint, mreal},
6    NumericArray, UninitNumericArray,
7};
8
9//======================================
10// Primitive data types
11//======================================
12
13#[wll::export]
14fn test_no_args() -> i64 {
15    4
16}
17
18#[wll::export]
19fn test_ret_void() {
20    // Do nothing.
21}
22
23//------------
24// mint, mreal
25//------------
26
27#[wll::export]
28fn test_mint(x: mint) -> mint {
29    x * x
30}
31
32// Test NativeFunction impl for raw function using raw MArguments.
33#[wll::export]
34fn test_raw_mint(args: &[wll::sys::MArgument], ret: wll::sys::MArgument) {
35    if args.len() != 1 {
36        panic!("unexpected number of arguments");
37    }
38
39    let x: mint = unsafe { *args[0].integer };
40
41    unsafe {
42        *ret.integer = x * x;
43    }
44}
45
46#[wll::export]
47fn test_mint_mint(x: mint, y: mint) -> mint {
48    x + y
49}
50
51#[wll::export]
52fn test_mreal(x: mreal) -> mreal {
53    x * x
54}
55
56//------------
57// i64, f64
58//------------
59
60#[wll::export]
61fn test_i64(x: i64) -> i64 {
62    x * x
63}
64
65#[wll::export]
66fn test_i64_i64(x: i64, y: i64) -> i64 {
67    x + y
68}
69
70#[wll::export]
71fn test_f64(x: f64) -> f64 {
72    x * x
73}
74
75//--------
76// Strings
77//--------
78
79// fn test_str(string: &str) -> String {
80//     string.chars().rev().collect()
81// }
82
83#[wll::export]
84fn test_string(string: String) -> String {
85    string.chars().rev().collect()
86}
87
88#[wll::export]
89fn test_c_string(string: CString) -> i64 {
90    i64::try_from(string.as_bytes().len()).expect("string len usize overflows i64")
91}
92
93//-------
94// Panics
95//-------
96
97#[wll::export]
98fn test_panic() {
99    panic!("this function panicked");
100}
101
102//======================================
103// NumericArray's
104//======================================
105
106#[wll::export]
107fn total_i64(list: &NumericArray<i64>) -> i64 {
108    list.as_slice().into_iter().sum()
109}
110
111/// Get the sign of every element in `list` as a numeric array of 0's and 1's.
112///
113/// The returned array will have the same dimensions as `list`.
114#[wll::export]
115fn positive_i64(list: &NumericArray<i64>) -> NumericArray<u8> {
116    let mut bools: UninitNumericArray<u8> =
117        UninitNumericArray::from_dimensions(list.dimensions());
118
119    for pair in list.as_slice().into_iter().zip(bools.as_slice_mut()) {
120        let (elem, entry): (&i64, &mut std::mem::MaybeUninit<u8>) = pair;
121
122        entry.write(u8::from(elem.is_positive()));
123    }
124
125    unsafe { bools.assume_init() }
126}