rssn_advanced/ffi_apis/
macros.rs

1#[macro_export]
2/// Creates a FFI-compatible function that takes a JSON string as input, deserializes it to a single argument,
3/// applies a body of logic, and returns the result as a JSON string.
4
5macro_rules! json_ffi_unary {
6    ($name:ident, $input_type:ty, | $arg:ident | $body:expr_2021) => {
7        #[no_mangle]
8
9        pub extern "C" fn $name(input_json : *const std::ffi::c_char) -> *mut std::ffi::c_char {
10
11            let input : Option<$input_type> =
12                $crate::ffi_apis::common::from_json_string(input_json);
13
14            if let Some($arg) = input {
15
16                let result = $body;
17
18                $crate::ffi_apis::common::to_json_string(&result)
19            } else {
20
21                std::ptr::null_mut()
22            }
23        }
24    };
25}
26
27#[macro_export]
28/// Creates a FFI-compatible function that takes two JSON strings as input, deserializes them to two arguments,
29/// applies a body of logic, and returns the result as a JSON string.
30
31macro_rules! json_ffi_binary {
32    ($name:ident, $input1_type:ty, $input2_type:ty, | $arg1:ident, $arg2:ident | $body:expr_2021) => {
33        #[no_mangle]
34
35        pub extern "C" fn $name(
36            input1_json : *const std::ffi::c_char,
37            input2_json : *const std::ffi::c_char,
38        ) -> *mut std::ffi::c_char {
39
40            let input1 : Option<$input1_type> =
41                $crate::ffi_apis::common::from_json_string(input1_json);
42
43            let input2 : Option<$input2_type> =
44                $crate::ffi_apis::common::from_json_string(input2_json);
45
46            if let (Some($arg1), Some($arg2)) = (input1, input2) {
47
48                let result = $body;
49
50                $crate::ffi_apis::common::to_json_string(&result)
51            } else {
52
53                std::ptr::null_mut()
54            }
55        }
56    };
57}
58
59#[macro_export]
60/// Creates a FFI-compatible function that takes a raw pointer to a single argument,
61/// dereferences it, applies a body of logic, and returns a raw pointer to the result.
62
63macro_rules! handle_ffi_unary {
64    ($name:ident, $input_type:ty, | $arg:ident | $body:expr_2021) => {
65        #[no_mangle]
66
67        pub extern "C" fn $name(input : *const $input_type) -> *mut $crate::symbolic::core::Expr {
68
69            let $arg = unsafe {
70
71                &*input
72            };
73
74            let result = $body;
75
76            Box::into_raw(Box::new(result))
77        }
78    };
79    // Generic return type version
80    ($name:ident, $input_type:ty, $ret_type:ty, | $arg:ident | $body:expr_2021) => {
81        #[no_mangle]
82
83        pub extern "C" fn $name(input : *const $input_type) -> *mut $ret_type {
84
85            let $arg = unsafe {
86
87                &*input
88            };
89
90            let result = $body;
91
92            Box::into_raw(Box::new(result))
93        }
94    };
95}
96
97#[macro_export]
98/// Creates a FFI-compatible function that takes raw pointers to two arguments,
99/// dereferences them, applies a body of logic, and returns a raw pointer to the result.
100
101macro_rules! handle_ffi_binary {
102    (
103        $name:ident,
104        $input1_type:ty,
105        $input2_type:ty,
106        $ret_type:ty, |
107        $arg1:ident,
108        $arg2:ident |
109        $body:expr_2021
110    ) => {
111        #[no_mangle]
112
113        pub extern "C" fn $name(
114            input1: *const $input1_type,
115            input2: *const $input2_type,
116        ) -> *mut $ret_type {
117
118            let $arg1 = unsafe {
119
120                &*input1
121            };
122
123            let $arg2 = unsafe {
124
125                &*input2
126            };
127
128            let result = $body;
129
130            Box::into_raw(Box::new(
131                result,
132            ))
133        }
134    };
135}
136
137#[macro_export]
138/// Creates a FFI-compatible function that takes a bincode buffer as input, deserializes it to a single argument,
139/// applies a body of logic, and returns the result as a bincode buffer.
140
141macro_rules! bincode_ffi_unary {
142    ($name:ident, $input_type:ty, | $arg:ident | $body:expr_2021) => {
143        #[no_mangle]
144
145        pub extern "C" fn $name(
146            input_buf : $crate::ffi_apis::common::BincodeBuffer
147        ) -> $crate::ffi_apis::common::BincodeBuffer {
148
149            let input : Option<$input_type> =
150                $crate::ffi_apis::common::from_bincode_buffer(&input_buf);
151
152            if let Some($arg) = input {
153
154                let result = $body;
155
156                $crate::ffi_apis::common::to_bincode_buffer(&result)
157            } else {
158
159                $crate::ffi_apis::common::BincodeBuffer::empty()
160            }
161        }
162    };
163}
164
165#[macro_export]
166/// Creates a FFI-compatible function that takes two bincode buffers as input, deserializes them to two arguments,
167/// applies a body of logic, and returns the result as a bincode buffer.
168
169macro_rules! bincode_ffi_binary {
170    ($name:ident, $input1_type:ty, $input2_type:ty, | $arg1:ident, $arg2:ident | $body:expr_2021) => {
171        #[no_mangle]
172
173        pub extern "C" fn $name(
174            input1_buf : $crate::ffi_apis::common::BincodeBuffer,
175            input2_buf : $crate::ffi_apis::common::BincodeBuffer,
176        ) -> $crate::ffi_apis::common::BincodeBuffer {
177
178            let input1 : Option<$input1_type> =
179                $crate::ffi_apis::common::from_bincode_buffer(&input1_buf);
180
181            let input2 : Option<$input2_type> =
182                $crate::ffi_apis::common::from_bincode_buffer(&input2_buf);
183
184            if let (Some($arg1), Some($arg2)) = (input1, input2) {
185
186                let result = $body;
187
188                $crate::ffi_apis::common::to_bincode_buffer(&result)
189            } else {
190
191                $crate::ffi_apis::common::BincodeBuffer::empty()
192            }
193        }
194    };
195}