diff --git a/rust/trexio/Cargo.toml b/rust/trexio/Cargo.toml index a2020e8..483c15f 100644 --- a/rust/trexio/Cargo.toml +++ b/rust/trexio/Cargo.toml @@ -10,3 +10,5 @@ edition = "2021" [build-dependencies] bindgen = "0.65.1" +[lib] +doctest = false diff --git a/rust/trexio/build.py b/rust/trexio/build.py index 3675b11..43931b7 100755 --- a/rust/trexio/build.py +++ b/rust/trexio/build.py @@ -91,6 +91,7 @@ impl File {""" ] for group in data: group_l = group.lower() r += [ """ +/// Checks if the group `{group}` exists in the file. pub fn has_{group_l}(&self) -> Result { let rc = unsafe { c::trexio_has_{group}(self.ptr) }; match rc { @@ -107,6 +108,7 @@ pub fn has_{group_l}(&self) -> Result { type_r = convert_r[data[group][element][0]] element_l = element.lower() r += [ """ +/// Checks if the element `{element}` of the group `{group}` exists in the file. pub fn has_{group_l}_{element_l}(&self) -> Result { let rc = unsafe { c::trexio_has_{group}_{element}(self.ptr) }; match rc { @@ -125,6 +127,7 @@ pub fn has_{group_l}_{element_l}(&self) -> Result { if data[group][element][1] == []: if data[group][element][0] in [ "int", "float", "dim", "index" ]: r += [ """ +/// Reads the scalar element `{element}` contained in the group `{group}`. pub fn read_{group_l}_{element_l}(&self) -> Result<{type_r}, ExitCode> { let mut data_c: {type_c} = 0{type_c}; let (rc, data) = unsafe { @@ -134,6 +137,7 @@ pub fn read_{group_l}_{element_l}(&self) -> Result<{type_r}, ExitCode> { rc_return(data, rc) } +/// Writes the scalar element `{element}` contained in the group `{group}`. pub fn write_{group_l}_{element_l}(&self, data: {type_r}) -> Result<(), ExitCode> { let data: {type_c} = data.try_into().expect("try_into failed in write_{group_l}_{element_l}"); let rc = unsafe { c::trexio_write_{group}_{element}_64(self.ptr, data) }; @@ -149,6 +153,7 @@ pub fn write_{group_l}_{element_l}(&self, data: {type_r}) -> Result<(), ExitCode elif data[group][element][0] in [ "str" ]: r += [ """ +/// Reads the string `{element}` contained in the group `{group}`. pub fn read_{group_l}_{element_l}(&self, capacity: usize) -> Result { let data_c = CString::new(vec![ b' ' ; capacity]).expect("CString::new failed"); let (rc, data) = unsafe { @@ -161,6 +166,7 @@ pub fn read_{group_l}_{element_l}(&self, capacity: usize) -> Result Result<(), ExitCode> { let size : i32 = data.len().try_into().expect("try_into failed in write_{group_l}_{element_l}"); let data = string_to_c(data); @@ -179,6 +185,7 @@ pub fn write_{group_l}_{element_l}(&self, data: &str) -> Result<(), ExitCode> { elif data[group][element][0] in [ "dim readonly" ]: r += [ """ +/// Reads the dimensioning variable `{element}` contained in group `{group}`. pub fn read_{group_l}_{element_l}(&self) -> Result<{type_r}, ExitCode> { let mut data_c: {type_c} = 0{type_c}; let (rc, data) = unsafe { @@ -199,7 +206,32 @@ pub fn read_{group_l}_{element_l}(&self) -> Result<{type_r}, ExitCode> { else: if data[group][element][0] in [ "int", "float", "dim", "index" ]: - t = [ """pub fn read_{group_l}_{element_l}(&self) -> Result, ExitCode> { + t = [ f""" +/// Reads the array `{element}` contained in the group `{group}`. +/// +/// Dimensions are `{data[group][element][1]}`. +/// """ ] + if len(data[group][element][1]) > 1: + t += [ f"""/// The array is returned as a flattened one-dimensional vector. +/// To put it back as a multidimensional array, you can use the [`chunks`] method: +/// +/// # Example +/// ``` +/// let one_d_array = trexio_file.read_{group_l}_{element_l}()?;""" ] + try: + dim_group, dim_element = data[group][element][1][0].split('.') + t += [ f"/// let {dim_group}_{dim_element} = trexio_file.read_{dim_group}_{dim_element}()?;", +f"/// let two_d_array = one_d_array.chunks({dim_group}_{dim_element}).collect();" +] + except: + t += [ f"/// let two_d_array = one_d_array.chunks({data[group][element][1][0]}).collect();" ] + t += [ """ +/// ``` +/// +/// [`chunks`]: slice::chunks""" +] + t += [ """ +pub fn read_{group_l}_{element_l}(&self) -> Result, ExitCode> { let size = 1;""" ] t_prime = [] for dim in data[group][element][1]: diff --git a/rust/trexio/src/back_end.rs b/rust/trexio/src/back_end.rs index b26ce7e..e1e4ba4 100644 --- a/rust/trexio/src/back_end.rs +++ b/rust/trexio/src/back_end.rs @@ -1,11 +1,16 @@ use crate::c; -/// Possible back ends #[derive(Debug)] #[derive(PartialEq)] pub enum BackEnd { + /// The TREXIO "file" is a directory with text files for each group. + /// A fallback when HDF5 is not available. Text, + + /// Should be used for production. The TREXIO file is a single HDF5 file. Hdf5, + + /// Automatic discovery of the appropriate backend Auto, } diff --git a/rust/trexio/src/exit_code.rs b/rust/trexio/src/exit_code.rs index 2e20958..60a7240 100644 --- a/rust/trexio/src/exit_code.rs +++ b/rust/trexio/src/exit_code.rs @@ -1,48 +1,104 @@ use crate::c; -/// Exit codes #[derive(Debug)] #[derive(PartialEq)] pub enum ExitCode { + /// Unknown failure Failure, + + /// Everything went fine Success, - InvalidArg1, - InvalidArg2, - InvalidArg3, - InvalidArg4, - InvalidArg5, + + /// Invalid argument + InvalidArg(usize), + + /// End of file End, + + /// Read-only file ReadOnly, + + /// Error returned by Errno Errno, + + /// Invalid ID InvalidId, + + /// Allocation failed AllocationFailed, + + /// Element absent HasNot, + + /// Invalid (negative or 0) dimension InvalidNum, + + /// Attribute already exists AttrAlreadyExists, + + /// Dataset already exists DsetAlreadyExists, + + /// Error opening file OpenError, + + /// Error locking file LockError, + + /// Error unlocking file UnlockError, + + /// Invalid file FileError, + + /// Error reading group GroupReadError, + + /// Error writing group GroupWriteError, + + /// Error reading element ElemReadError, + + /// Error writing element ElemWriteError, + + /// Access to memory beyond allocated UnsafeArrayDim, + + /// Attribute does not exist in the file AttrMissing, + + /// Dataset does not exist in the file DsetMissing, + + /// Requested back end is disabled BackEndMissing, - InvalidArg6, - InvalidArg7, - InvalidArg8, + + /// Invalid max_str_len InvalidStrLen, + + /// Possible integer overflow IntSizeOverflow, + + /// Unsafe operation in safe mode SafeMode, + + /// Inconsistent number of electrons InvalidElectronNum, + + /// Inconsistent number of determinants InvalidDeterminantNum, + + /// Inconsistent state of the file InvalidState, + + /// Failed to parse package_version VersionParsingIssue, + + /// The function succeeded with a change of sign PhaseChange, + } impl ExitCode { @@ -52,11 +108,11 @@ impl ExitCode { match rc { c::TREXIO_FAILURE => Self::Failure, c::TREXIO_SUCCESS => Self::Success, - c::TREXIO_INVALID_ARG_1 => Self::InvalidArg1, - c::TREXIO_INVALID_ARG_2 => Self::InvalidArg2, - c::TREXIO_INVALID_ARG_3 => Self::InvalidArg3, - c::TREXIO_INVALID_ARG_4 => Self::InvalidArg4, - c::TREXIO_INVALID_ARG_5 => Self::InvalidArg5, + c::TREXIO_INVALID_ARG_1 => Self::InvalidArg(1), + c::TREXIO_INVALID_ARG_2 => Self::InvalidArg(2), + c::TREXIO_INVALID_ARG_3 => Self::InvalidArg(3), + c::TREXIO_INVALID_ARG_4 => Self::InvalidArg(4), + c::TREXIO_INVALID_ARG_5 => Self::InvalidArg(5), c::TREXIO_END => Self::End, c::TREXIO_READONLY => Self::ReadOnly, c::TREXIO_ERRNO => Self::Errno, @@ -78,9 +134,9 @@ impl ExitCode { c::TREXIO_ATTR_MISSING => Self::AttrMissing, c::TREXIO_DSET_MISSING => Self::DsetMissing, c::TREXIO_BACK_END_MISSING => Self::BackEndMissing, - c::TREXIO_INVALID_ARG_6 => Self::InvalidArg6, - c::TREXIO_INVALID_ARG_7 => Self::InvalidArg7, - c::TREXIO_INVALID_ARG_8 => Self::InvalidArg8, + c::TREXIO_INVALID_ARG_6 => Self::InvalidArg(6), + c::TREXIO_INVALID_ARG_7 => Self::InvalidArg(7), + c::TREXIO_INVALID_ARG_8 => Self::InvalidArg(8), c::TREXIO_INVALID_STR_LEN => Self::InvalidStrLen, c::TREXIO_INT_SIZE_OVERFLOW => Self::IntSizeOverflow, c::TREXIO_SAFE_MODE => Self::SafeMode, @@ -98,11 +154,11 @@ impl ExitCode { match self { Self::Failure => c::TREXIO_FAILURE, Self::Success => c::TREXIO_SUCCESS, - Self::InvalidArg1 => c::TREXIO_INVALID_ARG_1, - Self::InvalidArg2 => c::TREXIO_INVALID_ARG_2, - Self::InvalidArg3 => c::TREXIO_INVALID_ARG_3, - Self::InvalidArg4 => c::TREXIO_INVALID_ARG_4, - Self::InvalidArg5 => c::TREXIO_INVALID_ARG_5, + Self::InvalidArg(1) => c::TREXIO_INVALID_ARG_1, + Self::InvalidArg(2) => c::TREXIO_INVALID_ARG_2, + Self::InvalidArg(3) => c::TREXIO_INVALID_ARG_3, + Self::InvalidArg(4) => c::TREXIO_INVALID_ARG_4, + Self::InvalidArg(5) => c::TREXIO_INVALID_ARG_5, Self::End => c::TREXIO_END, Self::ReadOnly => c::TREXIO_READONLY, Self::Errno => c::TREXIO_ERRNO, @@ -124,9 +180,9 @@ impl ExitCode { Self::AttrMissing => c::TREXIO_ATTR_MISSING, Self::DsetMissing => c::TREXIO_DSET_MISSING, Self::BackEndMissing => c::TREXIO_BACK_END_MISSING, - Self::InvalidArg6 => c::TREXIO_INVALID_ARG_6, - Self::InvalidArg7 => c::TREXIO_INVALID_ARG_7, - Self::InvalidArg8 => c::TREXIO_INVALID_ARG_8, + Self::InvalidArg(6) => c::TREXIO_INVALID_ARG_6, + Self::InvalidArg(7) => c::TREXIO_INVALID_ARG_7, + Self::InvalidArg(8) => c::TREXIO_INVALID_ARG_8, Self::InvalidStrLen => c::TREXIO_INVALID_STR_LEN, Self::IntSizeOverflow => c::TREXIO_INT_SIZE_OVERFLOW, Self::SafeMode => c::TREXIO_SAFE_MODE, @@ -135,6 +191,7 @@ impl ExitCode { Self::InvalidState => c::TREXIO_INVALID_STATE, Self::VersionParsingIssue => c::TREXIO_VERSION_PARSING_ISSUE, Self::PhaseChange => c::TREXIO_PHASE_CHANGE, + _ => panic!("Unknown exit code"), } } diff --git a/rust/trexio/src/lib.rs b/rust/trexio/src/lib.rs index 486346a..89292cb 100644 --- a/rust/trexio/src/lib.rs +++ b/rust/trexio/src/lib.rs @@ -1,20 +1,21 @@ use ::std::os::raw::c_char; /// C module generated by bindgen -pub mod c; +mod c; -/// Exit codes -pub mod exit_code; +/// Errors returned by function calls. These are related to the exit codes defined in the C TREXIO library. +mod exit_code; pub use exit_code::ExitCode; -/// Possible backends +/// Backends handled by TREXIO pub mod back_end; pub use back_end::BackEnd; -/// Bit fields +/// Bit fields, used for the description of determinants pub mod bitfield; pub use bitfield::Bitfield; +/// Version of the C TREXIO library pub const PACKAGE_VERSION : &str = unsafe { std::str::from_utf8_unchecked(c::TREXIO_PACKAGE_VERSION) }; fn rc_return(result: T, rc : c::trexio_exit_code) -> Result { @@ -30,6 +31,7 @@ fn string_to_c(s: &str) -> std::ffi::CString { } +/// Prints to standard output information about the C TREXIO library pub fn info() -> Result<(),ExitCode> { let rc = unsafe { c::trexio_info() }; rc_return((), rc)