mod events;
use std::{
ffi::{c_char, CStr, CString},
ptr::null_mut,
};
use twips::scramble::{
random_scramble_for_event, scramble_finder::free_memory_for_all_scramble_finders, Event,
};
#[no_mangle]
pub unsafe extern "C" fn ffi_random_scramble_for_event(
event_raw_cstr: *const c_char,
) -> *const c_char {
match ffi_random_scramble_for_event_internal(event_raw_cstr) {
Ok(scramble_raw_cstr) => scramble_raw_cstr,
Err(_) => null_mut(),
}
}
fn ffi_random_scramble_for_event_internal(
event_raw_cstr: *const c_char,
) -> Result<*const c_char, ()> {
let event_cstr = unsafe { CStr::from_ptr(event_raw_cstr) };
let event_str = event_cstr.to_str().map_err(|_| ())?;
let event = Event::try_from(event_str).map_err(|_| ())?;
let result_str = random_scramble_for_event(event)
.map_err(|_| ())?
.to_string();
Ok(CString::new(result_str).unwrap().into_raw())
}
#[test]
fn ffi_test() {
let test_data = [
("222", 11, 13), ("pyram", 11, 15), ("333", 15, 30),
("555", 60, 60),
("666", 80, 80),
("777", 100, 100),
("minx", 83, 83),
];
let dylib_path = test_cdylib::build_current_project();
let lib = unsafe { libloading::Library::new(dylib_path).unwrap() };
let func: libloading::Symbol<unsafe extern "C" fn(event_raw_cstr: *mut c_char) -> *mut c_char> =
unsafe { lib.get(b"ffi_random_scramble_for_event").unwrap() };
for (event_id, min_num_moves, max_num_moves) in test_data {
let event_raw_cstr = CString::new((event_id).to_owned()).unwrap().into_raw();
let scramble_raw_cstr = unsafe { func(event_raw_cstr) };
let scramble_cstr = unsafe { CStr::from_ptr(scramble_raw_cstr) };
let scramble_str = scramble_cstr.to_str().map_err(|_| ()).unwrap();
let alg = scramble_str.parse::<cubing::alg::Alg>().unwrap();
assert!(alg.nodes.len() >= min_num_moves);
assert!(alg.nodes.len() <= max_num_moves);
}
}
#[no_mangle]
pub extern "C" fn ffi_free_memory_for_all_scramble_finders() -> u32 {
free_memory_for_all_scramble_finders() as u32
}