pub unsafe extern "C" fn coord_vector_maker (input: *const c_char, x_lower: f64, x_upper: f64, y_lower: f64, y_upper: f64, x_precision: f64, y_precision: f64) -> *mut CoordPair<f64> {
let input_c_str: &CStr = CStr::from_ptr(input);
let str_slice: &str = input_c_str.to_str().unwrap();
let expression: String = str_slice.to_owned();
let x_all : Vec<f64> = x_vector_maker(x_lower, x_upper, x_precision);
let y_all : Vec<f64> = round_y_to_precision(func_of_x(expression, x_lower, x_upper, x_precision, y_lower, y_upper), y_precision);
let x_ptr = x_all.as_ptr();
let y_ptr = y_all.as_ptr();
let c_out = CoordPair::new(x_ptr, y_ptr);
Box::into_raw(Box::new(c_out))
}
pub fn func_of_x (expression: String, x_lower: f64, x_upper: f64, x_precision: f64, y_lower: f64, y_upper: f64) -> Vec<f64> {
let ys: Vec<f64> = make_all_x_strings(expression, x_lower, x_upper, x_precision).into_iter().map(|expr| infix_calculator(expr) as f64).collect();
ys //.into_iter().map(|y| if y >= y_lower && y <= y_upper { y } else { std::f64::NAN } ).collect()
}
pub fn infix_calculator(expression: String) -> f64 {
let mut s: s_y::ShuntingYard = s_y::ShuntingYard::new();
assert_eq!(s.calculate("2 + 3").unwrap(), 5.0);
let r: Result<f64, Vec<String>> = s.calculate(&expression);
match r {
Ok(result) => result,
Err(e) => {
println!("Errors: {:?}", e);
f64::NAN
}
}
}
this particular part is very ugly
pub fn make_all_x_strings (expression: String, x_lower: f64, x_upper: f64, x_precision: f64) -> Vec<String> {
let x_fl_vector = x_vector_maker(x_lower, x_upper, x_precision);
let x_string_vector: Vec<String> = x_fl_vector.into_iter().map(|x| expression.replace("x", &x.to_string())).collect();
x_string_vector
}
and unfortunately they are given "at runtime", the rust part of this is a stateless backend for a dart application