use std::os::raw::{c_int, c_uint};
use wolfram_library_link::{
expr::{Expr, Symbol},
sys::{
self as wll_sys, WolframLibraryData, LIBRARY_FUNCTION_ERROR, LIBRARY_NO_ERROR,
},
wstp::{
sys::{WSGetInteger, WSNewPacket, WSPutInteger, WSTestHead, WSLINK},
Link,
},
};
#[no_mangle]
pub unsafe extern "C" fn demo_wstp_function(
_lib: WolframLibraryData,
link: WSLINK,
) -> c_uint {
let mut i1: c_int = 0;
let mut i2: c_int = 0;
let mut len: c_int = 0;
if WSTestHead(link, b"List\0".as_ptr() as *const i8, &mut len) == 0 {
return LIBRARY_FUNCTION_ERROR;
}
if len != 2 {
return LIBRARY_FUNCTION_ERROR;
}
if WSGetInteger(link, &mut i1) == 0 {
return LIBRARY_FUNCTION_ERROR;
}
if WSGetInteger(link, &mut i2) == 0 {
return LIBRARY_FUNCTION_ERROR;
}
if WSNewPacket(link) == 0 {
return LIBRARY_FUNCTION_ERROR;
}
let sum = i1 + i2;
if WSPutInteger(link, sum) == 0 {
return LIBRARY_FUNCTION_ERROR;
}
return LIBRARY_NO_ERROR;
}
#[no_mangle]
pub extern "C" fn demo_wstp_function_callback(
lib: WolframLibraryData,
mut link: WSLINK,
) -> c_uint {
let link: &mut Link = unsafe { Link::unchecked_ref_cast_mut(&mut link) };
if link.raw_get_next().and_then(|_| link.new_packet()).is_err() {
return LIBRARY_FUNCTION_ERROR;
}
let callback_link = unsafe { (*lib).getWSLINK.unwrap()(lib) };
let mut callback_link = callback_link as wstp::sys::WSLINK;
{
let safe_callback_link =
unsafe { Link::unchecked_ref_cast_mut(&mut callback_link) };
safe_callback_link
.put_expr(&Expr::normal(Symbol::new("System`EvaluatePacket"), vec![
Expr::normal(Symbol::new("System`Print"), vec![Expr::string(
"Hello, World! --- WSTP",
)]),
]))
.unwrap();
unsafe {
(*lib).processWSLINK.unwrap()(
safe_callback_link.raw_link() as wll_sys::WSLINK
);
}
if safe_callback_link
.raw_get_next()
.and_then(|_| safe_callback_link.new_packet())
.is_err()
{
return LIBRARY_FUNCTION_ERROR;
}
}
link.put_expr(&Expr::string("returned normally")).unwrap();
return LIBRARY_NO_ERROR;
}
#[no_mangle]
pub extern "C" fn wstp_expr_function(
_lib: WolframLibraryData,
mut unsafe_link: WSLINK,
) -> c_uint {
let link: &mut Link = unsafe { Link::unchecked_ref_cast_mut(&mut unsafe_link) };
let expr = match link.get_expr() {
Ok(expr) => expr,
Err(err) => {
if link.raw_get_next().and_then(|_| link.new_packet()).is_err() {
return LIBRARY_FUNCTION_ERROR;
}
let err = Expr::string(err.to_string());
let err = Expr::normal(Symbol::new("System`Failure"), vec![
Expr::string("WSTP Error"),
Expr::normal(Symbol::new("System`Association"), vec![Expr::normal(
Symbol::new("System`Rule"),
vec![Expr::string("Message"), err],
)]),
]);
match link.put_expr(&err) {
Ok(()) => return LIBRARY_NO_ERROR,
Err(_) => return LIBRARY_FUNCTION_ERROR,
}
},
};
let expr_string = format!("Input: {}", expr.to_string());
match link.put_expr(&Expr::string(expr_string)) {
Ok(()) => LIBRARY_NO_ERROR,
Err(_) => LIBRARY_FUNCTION_ERROR,
}
}