use std::ffi::CStr;
use std::os::raw::c_char;
use crate::symbolic::core::Expr;
use crate::symbolic::integral_equations::FredholmEquation;
use crate::symbolic::integral_equations::FredholmEquationParams;
use crate::symbolic::integral_equations::VolterraEquation;
use crate::symbolic::integral_equations::VolterraEquationParams;
use crate::symbolic::integral_equations::solve_airfoil_equation;
#[unsafe(no_mangle)]
pub extern "C" fn rssn_fredholm_new(
y_x: *const Expr,
f_x: *const Expr,
lambda: *const Expr,
kernel: *const Expr,
lower_bound: *const Expr,
upper_bound: *const Expr,
var_x: *const c_char,
var_t: *const c_char,
) -> *mut FredholmEquation {
unsafe {
if y_x.is_null()
|| f_x.is_null()
|| lambda.is_null()
|| kernel.is_null()
|| lower_bound.is_null()
|| upper_bound.is_null()
|| var_x.is_null()
|| var_t.is_null()
{
return std::ptr::null_mut();
}
let var_x_str = match CStr::from_ptr(var_x).to_str() {
| Ok(s) => s.to_string(),
| Err(_) => return std::ptr::null_mut(),
};
let var_t_str = match CStr::from_ptr(var_t).to_str() {
| Ok(s) => s.to_string(),
| Err(_) => return std::ptr::null_mut(),
};
let params = FredholmEquationParams {
y_x: (*y_x).clone(),
f_x: (*f_x).clone(),
lambda: (*lambda).clone(),
kernel: (*kernel).clone(),
lower_bound: (*lower_bound).clone(),
upper_bound: (*upper_bound).clone(),
var_x: var_x_str,
var_t: var_t_str,
};
let eq = FredholmEquation::new(params);
Box::into_raw(Box::new(eq))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_fredholm_free(ptr: *mut FredholmEquation) {
if !ptr.is_null() {
unsafe {
let _ = Box::from_raw(ptr);
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_fredholm_solve_neumann(
eq: *const FredholmEquation,
iterations: usize,
) -> *mut Expr {
unsafe {
if eq.is_null() {
return std::ptr::null_mut();
}
let result = (*eq).solve_neumann_series(iterations);
Box::into_raw(Box::new(result))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_fredholm_solve_separable(
eq: *const FredholmEquation,
a_funcs: *const *const Expr,
a_len: usize,
b_funcs: *const *const Expr,
b_len: usize,
) -> *mut Expr {
unsafe {
if eq.is_null() || a_funcs.is_null() || b_funcs.is_null() {
return std::ptr::null_mut();
}
let a_slice = std::slice::from_raw_parts(a_funcs, a_len);
let b_slice = std::slice::from_raw_parts(b_funcs, b_len);
let mut a_vec = Vec::with_capacity(a_len);
for &ptr in a_slice {
if ptr.is_null() {
return std::ptr::null_mut();
}
a_vec.push((*ptr).clone());
}
let mut b_vec = Vec::with_capacity(b_len);
for &ptr in b_slice {
if ptr.is_null() {
return std::ptr::null_mut();
}
b_vec.push((*ptr).clone());
}
match (*eq).solve_separable_kernel(&a_vec, &b_vec) {
| Ok(result) => Box::into_raw(Box::new(result)),
| Err(_) => std::ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_volterra_new(
y_x: *const Expr,
f_x: *const Expr,
lambda: *const Expr,
kernel: *const Expr,
lower_bound: *const Expr,
var_x: *const c_char,
var_t: *const c_char,
) -> *mut VolterraEquation {
unsafe {
if y_x.is_null()
|| f_x.is_null()
|| lambda.is_null()
|| kernel.is_null()
|| lower_bound.is_null()
|| var_x.is_null()
|| var_t.is_null()
{
return std::ptr::null_mut();
}
let var_x_str = match CStr::from_ptr(var_x).to_str() {
| Ok(s) => s.to_string(),
| Err(_) => return std::ptr::null_mut(),
};
let var_t_str = match CStr::from_ptr(var_t).to_str() {
| Ok(s) => s.to_string(),
| Err(_) => return std::ptr::null_mut(),
};
let params = VolterraEquationParams {
y_x: (*y_x).clone(),
f_x: (*f_x).clone(),
lambda: (*lambda).clone(),
kernel: (*kernel).clone(),
lower_bound: (*lower_bound).clone(),
var_x: var_x_str,
var_t: var_t_str,
};
let eq = VolterraEquation::new(params);
Box::into_raw(Box::new(eq))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_volterra_free(ptr: *mut VolterraEquation) {
if !ptr.is_null() {
unsafe {
let _ = Box::from_raw(ptr);
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_volterra_solve_successive(
eq: *const VolterraEquation,
iterations: usize,
) -> *mut Expr {
unsafe {
if eq.is_null() {
return std::ptr::null_mut();
}
let result = (*eq).solve_successive_approximations(iterations);
Box::into_raw(Box::new(result))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_volterra_solve_by_differentiation(eq: *const VolterraEquation) -> *mut Expr {
unsafe {
if eq.is_null() {
return std::ptr::null_mut();
}
match (*eq).solve_by_differentiation() {
| Ok(result) => Box::into_raw(Box::new(result)),
| Err(_) => std::ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_solve_airfoil_equation(
f_x: *const Expr,
var_x: *const c_char,
var_t: *const c_char,
) -> *mut Expr {
unsafe {
if f_x.is_null() || var_x.is_null() || var_t.is_null() {
return std::ptr::null_mut();
}
let var_x_str = match CStr::from_ptr(var_x).to_str() {
| Ok(s) => s,
| Err(_) => return std::ptr::null_mut(),
};
let var_t_str = match CStr::from_ptr(var_t).to_str() {
| Ok(s) => s,
| Err(_) => return std::ptr::null_mut(),
};
let result = solve_airfoil_equation(&(*f_x), var_x_str, var_t_str);
Box::into_raw(Box::new(result))
}
}