move check_code to lib

This commit is contained in:
daniel
2020-11-10 17:22:43 +01:00
parent 56a15b7a41
commit 7a22031bee
2 changed files with 63 additions and 27 deletions

View File

@@ -58,21 +58,6 @@ impl Error {
pub fn is_eof(&self) -> bool { pub fn is_eof(&self) -> bool {
self.code().map_or(false, |e| e.is_eof()) 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<T>(code: impl Into<ErrorCode>, value: T, task: ErrorTask) -> Result<T, Self> {
let code: ErrorCode = code.into();
if let ErrorCode::ExdrOk = code {
Ok(value)
} else {
Err(Self::CApiError { code, task })
}
}
} }
impl std::error::Error for Error { 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<std::ffi::NulError> for Error { impl From<std::ffi::NulError> for Error {
fn from(err: std::ffi::NulError) -> Self { fn from(err: std::ffi::NulError) -> Self {
Self::NullInStr(err) Self::NullInStr(err)

View File

@@ -105,6 +105,21 @@ fn path_to_cstring(path: impl AsRef<Path>) -> Result<CString> {
CString::new(s).map_err(Error::from) 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<ErrorCode>, task: ErrorTask) -> Option<Error> {
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 /// A safe wrapper around the c implementation of an XDRFile
struct XDRFile { struct XDRFile {
xdrfile: *mut XDRFILE, xdrfile: *mut XDRFILE,
@@ -135,10 +150,7 @@ impl XDRFile {
}) })
} else { } else {
// Something went wrong. But the C api does not tell us what // Something went wrong. But the C api does not tell us what
Err(Error::CouldNotOpen { Err(Error::from((path, filemode)))
path: path.to_owned(),
mode: filemode
})
} }
} }
} }
@@ -226,7 +238,11 @@ impl Trajectory for XTCTrajectory {
&mut self.precision.get(), &mut self.precision.get(),
) as u32; ) as u32;
frame.step = step 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], frame.coords[..].as_ptr() as *mut [f32; 3],
1000.0, 1000.0,
) as u32; ) 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<()> { fn flush(&mut self) -> Result<()> {
unsafe { unsafe {
let code = xdr_seek::xdr_flush(self.handle.xdrfile) as u32; 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 // Reconstitute the CString so it is deallocated correctly
let _ = CString::from_raw(path_p); 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() .clone()
@@ -332,7 +360,11 @@ impl Trajectory for TRRTrajectory {
std::ptr::null_mut(), std::ptr::null_mut(),
) as u32; ) as u32;
frame.step = step 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(),
std::ptr::null_mut(), std::ptr::null_mut(),
) as u32; ) 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<()> { fn flush(&mut self) -> Result<()> {
unsafe { unsafe {
let code = xdr_seek::xdr_flush(self.handle.xdrfile) as u32; 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 // Reconstitute the CString so it is deallocated correctly
let _ = CString::from_raw(path_p); 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() .clone()