diff --git a/src/errors.rs b/src/errors.rs index 99cb1ba..f92011f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -58,21 +58,6 @@ impl Error { pub fn is_eof(&self) -> bool { self.code().map_or(false, |e| e.is_eof()) } - - /// Convert an error code and output value from a C call to a Result - /// - /// `code` should be an integer return code returned from the C API. `value` should be the - /// function's output, which is generally either `()` or one of its arguments. If `code` - /// indicates the function returned successfully, the value is returned; otherwise, the - /// code is converted into the appropriate `Error`. - pub fn check_code(code: impl Into, value: T, task: ErrorTask) -> Result { - let code: ErrorCode = code.into(); - if let ErrorCode::ExdrOk = code { - Ok(value) - } else { - Err(Self::CApiError { code, task }) - } - } } impl std::error::Error for Error { @@ -85,6 +70,13 @@ impl std::error::Error for Error { } } +impl From<(ErrorCode, ErrorTask)> for Error { + fn from(value: (ErrorCode, ErrorTask)) -> Self { + let (code, task) = value; + Self::CApiError { code, task } + } +} + impl From for Error { fn from(err: std::ffi::NulError) -> Self { Self::NullInStr(err) diff --git a/src/lib.rs b/src/lib.rs index 2cc3a96..3dab368 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,6 +105,21 @@ fn path_to_cstring(path: impl AsRef) -> Result { CString::new(s).map_err(Error::from) } +/// Convert an error code from a C call to an Error +/// +/// `code` should be an integer return code returned from the C API. +/// If `code` indicates the function returned successfully, Nothing is returned; +/// otherwise, the code is converted into the appropriate `Error`. +pub fn check_code(code: impl Into, task: ErrorTask) -> Option { + let code: ErrorCode = code.into(); + if let ErrorCode::ExdrOk = code { + None + } else { + Some(Error::from((code, task))) + } +} + + /// A safe wrapper around the c implementation of an XDRFile struct XDRFile { xdrfile: *mut XDRFILE, @@ -135,10 +150,7 @@ impl XDRFile { }) } else { // Something went wrong. But the C api does not tell us what - Err(Error::CouldNotOpen { - path: path.to_owned(), - mode: filemode - }) + Err(Error::from((path, filemode))) } } } @@ -226,7 +238,11 @@ impl Trajectory for XTCTrajectory { &mut self.precision.get(), ) as u32; frame.step = step as u32; - Error::check_code(code, (), ErrorTask::Read) + if let Some(err) = check_code(code, ErrorTask::Read) { + Err(err) + } else { + Ok(()) + } } } @@ -241,14 +257,22 @@ impl Trajectory for XTCTrajectory { frame.coords[..].as_ptr() as *mut [f32; 3], 1000.0, ) as u32; - Error::check_code(code, (), ErrorTask::Write) + if let Some(err) = check_code(code, ErrorTask::Write) { + Err(err) + } else { + Ok(()) + } } } fn flush(&mut self) -> Result<()> { unsafe { let code = xdr_seek::xdr_flush(self.handle.xdrfile) as u32; - Error::check_code(code, (), ErrorTask::Flush) + if let Some(err) = check_code(code, ErrorTask::Read) { + Err(err) + } else { + Ok(()) + } } } @@ -265,7 +289,11 @@ impl Trajectory for XTCTrajectory { // Reconstitute the CString so it is deallocated correctly let _ = CString::from_raw(path_p); - Error::check_code(code, num_atoms as u32, ErrorTask::ReadNumAtoms) + if let Some(err) = check_code(code, ErrorTask::ReadNumAtoms) { + Err(err) + } else { + Ok(num_atoms as u32) + } } }) .clone() @@ -332,7 +360,11 @@ impl Trajectory for TRRTrajectory { std::ptr::null_mut(), ) as u32; frame.step = step as u32; - Error::check_code(code, (), ErrorTask::Read) + if let Some(err) = check_code(code, ErrorTask::Read) { + Err(err) + } else { + Ok(()) + } } } @@ -349,14 +381,22 @@ impl Trajectory for TRRTrajectory { std::ptr::null_mut(), std::ptr::null_mut(), ) as u32; - Error::check_code(code, (), ErrorTask::Write) + if let Some(err) = check_code(code, ErrorTask::Write) { + Err(err) + } else { + Ok(()) + } } } fn flush(&mut self) -> Result<()> { unsafe { let code = xdr_seek::xdr_flush(self.handle.xdrfile) as u32; - Error::check_code(code, (), ErrorTask::Flush) + if let Some(err) = check_code(code, ErrorTask::Flush) { + Err(err) + } else { + Ok(()) + } } } @@ -372,7 +412,11 @@ impl Trajectory for TRRTrajectory { // Reconstitute the CString so it is deallocated correctly let _ = CString::from_raw(path_p); - Error::check_code(code, num_atoms as u32, ErrorTask::ReadNumAtoms) + if let Some(err) = check_code(code, ErrorTask::ReadNumAtoms) { + Err(err) + } else { + Ok(num_atoms as u32) + } } }) .clone()