use std::os::raw::{c_int, c_uint};
use wolfram_library_link::{
expr::{expr, Expr},
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!(
System::EvaluatePacket[System::Print["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 msg = err.to_string();
let err = wolfram_library_link::expr::expr!(
System::Failure["WSTP Error", {"Message" -> msg}]
);
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,
}
}