mirror of
https://github.com/dnlbauer/xdrfile.git
synced 2026-09-10 22:25:30 +00:00
Replace failure library with new Error type
This commit is contained in:
@@ -8,7 +8,6 @@ description = "Wrapper around the gromacs libxdrfile library. Can be used to rea
|
|||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
failure = "0.1"
|
|
||||||
lazy-init = "0.3"
|
lazy-init = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use crate::c_abi::xdrfile::exdrENDOFFILE;
|
use crate::c_abi::xdrfile::exdrENDOFFILE;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use failure::Error;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
impl IntoIterator for XTCTrajectory {
|
impl IntoIterator for XTCTrajectory {
|
||||||
type Item = Result<Rc<Frame>, Error>;
|
type Item = Result<Rc<Frame>>;
|
||||||
type IntoIter = XTCTrajectoryIterator;
|
type IntoIter = XTCTrajectoryIterator;
|
||||||
|
|
||||||
fn into_iter(mut self) -> Self::IntoIter {
|
fn into_iter(mut self) -> Self::IntoIter {
|
||||||
@@ -30,7 +29,7 @@ pub struct XTCTrajectoryIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for XTCTrajectoryIterator {
|
impl Iterator for XTCTrajectoryIterator {
|
||||||
type Item = Result<Rc<Frame>, Error>;
|
type Item = Result<Rc<Frame>>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
// Reuse old frame
|
// Reuse old frame
|
||||||
@@ -61,7 +60,7 @@ impl Iterator for XTCTrajectoryIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for TRRTrajectory {
|
impl IntoIterator for TRRTrajectory {
|
||||||
type Item = Result<Rc<Frame>, Error>;
|
type Item = Result<Rc<Frame>>;
|
||||||
type IntoIter = TRRTrajectoryIterator;
|
type IntoIter = TRRTrajectoryIterator;
|
||||||
|
|
||||||
fn into_iter(mut self) -> Self::IntoIter {
|
fn into_iter(mut self) -> Self::IntoIter {
|
||||||
@@ -87,7 +86,7 @@ pub struct TRRTrajectoryIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for TRRTrajectoryIterator {
|
impl Iterator for TRRTrajectoryIterator {
|
||||||
type Item = Result<Rc<Frame>, Error>;
|
type Item = Result<Rc<Frame>>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
// Reuse old frame
|
// Reuse old frame
|
||||||
|
|||||||
183
src/lib.rs
183
src/lib.rs
@@ -75,12 +75,59 @@ use c_abi::xdrfile::XDRFILE;
|
|||||||
use c_abi::xdrfile_trr;
|
use c_abi::xdrfile_trr;
|
||||||
use c_abi::xdrfile_xtc;
|
use c_abi::xdrfile_xtc;
|
||||||
|
|
||||||
use failure::{err_msg, Error};
|
|
||||||
use lazy_init::Lazy;
|
use lazy_init::Lazy;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Error {
|
||||||
|
CouldNotOpenFile(std::path::PathBuf, FileMode),
|
||||||
|
CouldNotReadAtomNumber(u32),
|
||||||
|
CouldNotRead(u32),
|
||||||
|
CouldNotWrite(u32),
|
||||||
|
CouldNotFlush(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
use Error::*;
|
||||||
|
match self {
|
||||||
|
CouldNotOpenFile(path, mode) => write!(
|
||||||
|
f,
|
||||||
|
"Failed to open file at {path:?} with mode {mode:?}",
|
||||||
|
path = path,
|
||||||
|
mode = mode
|
||||||
|
),
|
||||||
|
CouldNotReadAtomNumber(code) => write!(
|
||||||
|
f,
|
||||||
|
"Failed to read atom number from trajectory: C API returned error code {}",
|
||||||
|
code
|
||||||
|
),
|
||||||
|
CouldNotRead(code) => write!(
|
||||||
|
f,
|
||||||
|
"Failed to read trajectory: C API returned error code {}",
|
||||||
|
code
|
||||||
|
),
|
||||||
|
CouldNotWrite(code) => write!(
|
||||||
|
f,
|
||||||
|
"Failed to write trajectory: C API returned error code {}",
|
||||||
|
code
|
||||||
|
),
|
||||||
|
CouldNotFlush(code) => write!(
|
||||||
|
f,
|
||||||
|
"Failed to flush trajectory: C API returned error code {}",
|
||||||
|
code
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub enum FileMode {
|
pub enum FileMode {
|
||||||
Write,
|
Write,
|
||||||
Append,
|
Append,
|
||||||
@@ -110,7 +157,7 @@ struct XDRFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl XDRFile {
|
impl XDRFile {
|
||||||
pub fn open(path: &Path, filemode: FileMode) -> Result<XDRFile, Error> {
|
pub fn open(path: &Path, filemode: FileMode) -> Result<XDRFile> {
|
||||||
let path_p = path_to_cstring(path).into_raw();
|
let path_p = path_to_cstring(path).into_raw();
|
||||||
let mode_p = CString::new(filemode.value()).unwrap().into_raw();
|
let mode_p = CString::new(filemode.value()).unwrap().into_raw();
|
||||||
|
|
||||||
@@ -126,7 +173,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(err_msg("Failed to open trajectory file"))
|
Err(Error::CouldNotOpenFile(path.into(), filemode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,27 +191,27 @@ impl Drop for XDRFile {
|
|||||||
/// The trajectory trait defines shared methods for xtc and trr trajectories
|
/// The trajectory trait defines shared methods for xtc and trr trajectories
|
||||||
pub trait Trajectory {
|
pub trait Trajectory {
|
||||||
/// Read the next step of the trajectory into the frame object
|
/// Read the next step of the trajectory into the frame object
|
||||||
fn read(&mut self, frame: &mut Frame) -> Result<(), Error>;
|
fn read(&mut self, frame: &mut Frame) -> Result<()>;
|
||||||
|
|
||||||
/// Write the frame to the trajectory file
|
/// Write the frame to the trajectory file
|
||||||
fn write(&mut self, frame: &Frame) -> Result<(), Error>;
|
fn write(&mut self, frame: &Frame) -> Result<()>;
|
||||||
|
|
||||||
/// Flush the trajectory file
|
/// Flush the trajectory file
|
||||||
fn flush(&mut self) -> Result<(), Error>;
|
fn flush(&mut self) -> Result<()>;
|
||||||
|
|
||||||
/// Get the number of atoms from the give trajectory
|
/// Get the number of atoms from the give trajectory
|
||||||
fn get_num_atoms(&mut self) -> Result<u32, Error>;
|
fn get_num_atoms(&mut self) -> Result<u32>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read/Write XTC Trajectories
|
/// Read/Write XTC Trajectories
|
||||||
pub struct XTCTrajectory {
|
pub struct XTCTrajectory {
|
||||||
handle: XDRFile,
|
handle: XDRFile,
|
||||||
precision: Cell<f32>, // internal mutability required for read method
|
precision: Cell<f32>, // internal mutability required for read method
|
||||||
num_atoms: Lazy<Result<u32, Error>>,
|
num_atoms: Lazy<Result<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XTCTrajectory {
|
impl XTCTrajectory {
|
||||||
pub fn open(path: &Path, filemode: FileMode) -> Result<XTCTrajectory, Error> {
|
pub fn open(path: &Path, filemode: FileMode) -> Result<XTCTrajectory> {
|
||||||
let xdr = XDRFile::open(path, filemode)?;
|
let xdr = XDRFile::open(path, filemode)?;
|
||||||
Ok(XTCTrajectory {
|
Ok(XTCTrajectory {
|
||||||
handle: xdr,
|
handle: xdr,
|
||||||
@@ -175,7 +222,7 @@ impl XTCTrajectory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Trajectory for XTCTrajectory {
|
impl Trajectory for XTCTrajectory {
|
||||||
fn read(&mut self, frame: &mut Frame) -> Result<(), Error> {
|
fn read(&mut self, frame: &mut Frame) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// C lib requires an i32 to be passed, but step is exposed it as u32
|
// C lib requires an i32 to be passed, but step is exposed it as u32
|
||||||
// (A step cannot be negative, can it?). So we need to create a step
|
// (A step cannot be negative, can it?). So we need to create a step
|
||||||
@@ -193,15 +240,12 @@ impl Trajectory for XTCTrajectory {
|
|||||||
frame.step = step as u32;
|
frame.step = step as u32;
|
||||||
match code {
|
match code {
|
||||||
xdrfile::exdrOK => Ok(()),
|
xdrfile::exdrOK => Ok(()),
|
||||||
_ => Err(err_msg(format!(
|
_ => Err(Error::CouldNotRead(code)),
|
||||||
"Failed to read trajectory. Error code: {}",
|
|
||||||
code
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, frame: &Frame) -> Result<(), Error> {
|
fn write(&mut self, frame: &Frame) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let code = xdrfile_xtc::write_xtc(
|
let code = xdrfile_xtc::write_xtc(
|
||||||
self.handle.xdrfile,
|
self.handle.xdrfile,
|
||||||
@@ -214,60 +258,48 @@ impl Trajectory for XTCTrajectory {
|
|||||||
) as u32;
|
) as u32;
|
||||||
match code {
|
match code {
|
||||||
xdrfile::exdrOK => Ok(()),
|
xdrfile::exdrOK => Ok(()),
|
||||||
_ => Err(err_msg(format!(
|
_ => Err(Error::CouldNotWrite(code)),
|
||||||
"Failed to write trajectory. Error code: {}",
|
|
||||||
code
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), Error> {
|
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;
|
||||||
match code {
|
match code {
|
||||||
xdrfile::exdrOK => Ok(()),
|
xdrfile::exdrOK => Ok(()),
|
||||||
_ => Err(err_msg(format!(
|
_ => Err(Error::CouldNotFlush(code)),
|
||||||
"Failed to flush trajectory. Error code: {}",
|
|
||||||
code
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_num_atoms(&mut self) -> Result<u32, Error> {
|
fn get_num_atoms(&mut self) -> Result<u32> {
|
||||||
let result = self.num_atoms.get_or_create(|| {
|
self.num_atoms
|
||||||
let mut num_atoms: i32 = 0;
|
.get_or_create(|| {
|
||||||
unsafe {
|
let mut num_atoms: i32 = 0;
|
||||||
let path = CString::new(self.handle.path.as_str()).unwrap();
|
unsafe {
|
||||||
let path_p = path.into_raw();
|
let path = CString::new(self.handle.path.as_str()).unwrap();
|
||||||
let code =
|
let path_p = path.into_raw();
|
||||||
xdrfile_xtc::read_xtc_natoms(path_p, &mut num_atoms as *const i32) as u32;
|
let code =
|
||||||
match code {
|
xdrfile_xtc::read_xtc_natoms(path_p, &mut num_atoms as *const i32) as u32;
|
||||||
xdrfile::exdrOK => Ok(num_atoms as u32),
|
match code {
|
||||||
_ => Err(err_msg(format!(
|
xdrfile::exdrOK => Ok(num_atoms as u32),
|
||||||
"Failed to read atom number from trajectory. Error code: {}",
|
_ => Err(Error::CouldNotReadAtomNumber(code)),
|
||||||
code
|
}
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
});
|
.clone()
|
||||||
match result {
|
|
||||||
Ok(val) => Ok(*val),
|
|
||||||
// ugly hack because failure::Error is not "Clone"
|
|
||||||
Err(err) => Err(err_msg(format!("{}", err))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read/Write TRR Trajectories
|
/// Read/Write TRR Trajectories
|
||||||
pub struct TRRTrajectory {
|
pub struct TRRTrajectory {
|
||||||
handle: XDRFile,
|
handle: XDRFile,
|
||||||
num_atoms: Lazy<Result<u32, Error>>,
|
num_atoms: Lazy<Result<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TRRTrajectory {
|
impl TRRTrajectory {
|
||||||
pub fn open(path: &Path, filemode: FileMode) -> Result<TRRTrajectory, Error> {
|
pub fn open(path: &Path, filemode: FileMode) -> Result<TRRTrajectory> {
|
||||||
let xdr = XDRFile::open(path, filemode)?;
|
let xdr = XDRFile::open(path, filemode)?;
|
||||||
Ok(TRRTrajectory {
|
Ok(TRRTrajectory {
|
||||||
handle: xdr,
|
handle: xdr,
|
||||||
@@ -277,7 +309,7 @@ impl TRRTrajectory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Trajectory for TRRTrajectory {
|
impl Trajectory for TRRTrajectory {
|
||||||
fn read(&mut self, frame: &mut Frame) -> Result<(), Error> {
|
fn read(&mut self, frame: &mut Frame) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// C lib requires an i32 to be passed, but step is exposed it as u32
|
// C lib requires an i32 to be passed, but step is exposed it as u32
|
||||||
// (A step cannot be negative, can it?). So we need to create a step
|
// (A step cannot be negative, can it?). So we need to create a step
|
||||||
@@ -299,15 +331,12 @@ impl Trajectory for TRRTrajectory {
|
|||||||
frame.step = step as u32;
|
frame.step = step as u32;
|
||||||
match code {
|
match code {
|
||||||
xdrfile::exdrOK => Ok(()),
|
xdrfile::exdrOK => Ok(()),
|
||||||
_ => Err(err_msg(format!(
|
_ => Err(Error::CouldNotRead(code)),
|
||||||
"Failed to read trajectory. Error code: {}",
|
|
||||||
code
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, frame: &Frame) -> Result<(), Error> {
|
fn write(&mut self, frame: &Frame) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let code = xdrfile_trr::write_trr(
|
let code = xdrfile_trr::write_trr(
|
||||||
self.handle.xdrfile,
|
self.handle.xdrfile,
|
||||||
@@ -322,49 +351,37 @@ impl Trajectory for TRRTrajectory {
|
|||||||
) as u32;
|
) as u32;
|
||||||
match code {
|
match code {
|
||||||
xdrfile::exdrOK => Ok(()),
|
xdrfile::exdrOK => Ok(()),
|
||||||
_ => Err(err_msg(format!(
|
_ => Err(Error::CouldNotWrite(code)),
|
||||||
"Failed to write trajectory. Error code: {}",
|
|
||||||
code
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), Error> {
|
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;
|
||||||
match code {
|
match code {
|
||||||
xdrfile::exdrOK => Ok(()),
|
xdrfile::exdrOK => Ok(()),
|
||||||
_ => Err(err_msg(format!(
|
_ => Err(Error::CouldNotFlush(code)),
|
||||||
"Failed to flush trajectory. Error code: {}",
|
|
||||||
code
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_num_atoms(&mut self) -> Result<u32, Error> {
|
fn get_num_atoms(&mut self) -> Result<u32> {
|
||||||
let result = self.num_atoms.get_or_create(|| {
|
self.num_atoms
|
||||||
let mut num_atoms: i32 = 0;
|
.get_or_create(|| {
|
||||||
unsafe {
|
let mut num_atoms: i32 = 0;
|
||||||
let path = CString::new(self.handle.path.as_str()).unwrap();
|
unsafe {
|
||||||
let path_p = path.into_raw();
|
let path = CString::new(self.handle.path.as_str()).unwrap();
|
||||||
let code =
|
let path_p = path.into_raw();
|
||||||
xdrfile_trr::read_trr_natoms(path_p, &mut num_atoms as *const i32) as u32;
|
let code =
|
||||||
match code {
|
xdrfile_trr::read_trr_natoms(path_p, &mut num_atoms as *const i32) as u32;
|
||||||
xdrfile::exdrOK => Ok(num_atoms as u32),
|
match code {
|
||||||
_ => Err(err_msg(format!(
|
xdrfile::exdrOK => Ok(num_atoms as u32),
|
||||||
"Failed to read atom number from trajectory. Error code: {}",
|
_ => Err(Error::CouldNotReadAtomNumber(code)),
|
||||||
code
|
}
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
});
|
.clone()
|
||||||
match result {
|
|
||||||
Ok(val) => Ok(*val),
|
|
||||||
// ugly hack because failure::Error is not "Clone"
|
|
||||||
Err(err) => Err(err_msg(format!("{}", err))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user