use ::std::os::raw::c_char;
mod c;
pub mod exit_code;
pub use exit_code::ExitCode;
use exit_code::ExitCode::InvalidArg;
pub mod back_end;
pub use back_end::BackEnd;
pub mod bitfield;
pub use bitfield::Bitfield;
pub const PACKAGE_VERSION: &str =
unsafe { std::str::from_utf8_unchecked(c::TREXIO_PACKAGE_VERSION) };
fn rc_return<T>(result: T, rc: c::trexio_exit_code) -> Result<T, ExitCode> {
let rc = ExitCode::from(rc);
match rc {
ExitCode::Success => Ok(result),
x => Err(x),
}
}
fn string_to_c(s: &str) -> std::ffi::CString {
std::ffi::CString::new(s).unwrap()
}
pub fn info() -> Result<(), ExitCode> {
let rc = unsafe { c::trexio_info() };
rc_return((), rc)
}
pub struct File {
ptr: *mut c::trexio_t,
}
impl File {
pub fn open(file_name: &str, mode: char, back_end: BackEnd) -> Result<File, ExitCode> {
let file_name_c = string_to_c(file_name);
let file_name_c = file_name_c.as_ptr() as *const c_char;
let mode = mode as c_char;
let back_end = back_end.to_c();
let rc: *mut c::trexio_exit_code = &mut c::TREXIO_SUCCESS.clone();
let result = unsafe { c::trexio_open(file_name_c, mode, back_end, rc) };
let rc = unsafe { *rc };
rc_return(File { ptr: result }, rc)
}
pub fn close(self) -> Result<(), ExitCode> {
let rc = unsafe { c::trexio_close(self.ptr) };
rc_return((), rc)
}
pub fn inquire(file_name: &str) -> Result<bool, ExitCode> {
let file_name_c = string_to_c(file_name);
let file_name_c = file_name_c.as_ptr() as *const c_char;
let rc = unsafe { c::trexio_inquire(file_name_c) };
match ExitCode::from(rc) {
ExitCode::Failure => Ok(false),
ExitCode::Success => Ok(true),
x => Err(x),
}
}
pub fn get_state(&self) -> Result<usize, ExitCode> {
let mut num = 0i32;
let rc = unsafe { c::trexio_get_state(self.ptr, &mut num) };
let result: usize = num.try_into().expect("try_into failed in get_state");
rc_return(result, rc)
}
pub fn set_state(&self, num: usize) -> Result<(), ExitCode> {
let num: i32 = num.try_into().expect("try_into failed in set_state");
let rc = unsafe { c::trexio_set_state(self.ptr, num) };
rc_return((), rc)
}
pub fn get_int64_num(&self) -> Result<usize, ExitCode> {
let mut num = 0i32;
let rc = unsafe { c::trexio_get_int64_num(self.ptr, &mut num) };
let num: usize = num.try_into().expect("try_into failed in get_int64_num");
rc_return(num, rc)
}
pub fn write_determinant_list(
&self,
offset: usize,
determinants: &[Bitfield],
) -> Result<(), ExitCode> {
let n_int = self.get_int64_num()?;
match determinants.len() {
0 => return Ok(()),
_ => {
if determinants[0].as_vec().len() != 2 * n_int {
return Err(InvalidArg(3));
}
}
};
let offset: i64 = offset
.try_into()
.expect("try_into failed in write_determinant_list");
let buffer_size: i64 = determinants
.len()
.try_into()
.expect("try_into failed in write_determinant_list");
let mut one_d_array: Vec<i64> = Vec::with_capacity(determinants.len() * n_int);
for det in determinants {
for i in det.as_vec() {
one_d_array.push(*i);
}
}
let dset: *const i64 = one_d_array.as_ptr();
let rc = unsafe { c::trexio_write_determinant_list(self.ptr, offset, buffer_size, dset) };
rc_return((), rc)
}
pub fn read_determinant_list(
&self,
offset: usize,
buffer_size: usize,
) -> Result<Vec<Bitfield>, ExitCode> {
let n_int = self.get_int64_num()?;
let mut one_d_array: Vec<i64> = Vec::with_capacity(buffer_size * 2 * n_int);
let one_d_array_ptr = one_d_array.as_ptr() as *mut i64;
let rc = unsafe {
let offset: i64 = offset
.try_into()
.expect("try_into failed in read_determinant_list (offset)");
let mut buffer_size_read: i64 = buffer_size
.try_into()
.expect("try_into failed in read_determinant_list (buffer_size)");
let rc = c::trexio_read_determinant_list(
self.ptr,
offset,
&mut buffer_size_read,
one_d_array_ptr,
);
let buffer_size_read: usize = buffer_size_read
.try_into()
.expect("try_into failed in read_determinant_list (buffer_size)");
one_d_array.set_len(n_int * 2usize * buffer_size_read);
match ExitCode::from(rc) {
ExitCode::End => ExitCode::to_c(&ExitCode::Success),
ExitCode::Success => {
assert_eq!(buffer_size_read, buffer_size);
rc
}
_ => rc,
}
};
let result: Vec<Bitfield> = one_d_array
.chunks(2 * n_int)
.collect::<Vec<_>>()
.iter()
.map(|x| (Bitfield::from_vec(x)))
.collect::<Vec<_>>();
rc_return(result, rc)
}
}
include!(concat!(env!("OUT_DIR"), "/generated.rs"));