mirror of
https://github.com/dnlbauer/xdrfile.git
synced 2026-09-10 14:15:31 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4483f8a94 | ||
|
|
faaa335e37 | ||
|
|
ee9158555e | ||
|
|
a29faf9d63 | ||
|
|
3b89309b8b | ||
|
|
daccb110db | ||
|
|
8ce523cb68 | ||
|
|
b1d92ab150 | ||
|
|
49f77c672a | ||
|
|
53c668631d | ||
|
|
5b7247962e |
@@ -4,6 +4,6 @@ rust:
|
|||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
git:
|
git:
|
||||||
depth: 10
|
depth: 50
|
||||||
after_success:
|
after_success:
|
||||||
./.travis_bench.sh
|
./.travis_bench.sh
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ version = "0.3.0"
|
|||||||
authors = ["Daniel Bauer <bauer@cbs.tu-darmstadt.de>"]
|
authors = ["Daniel Bauer <bauer@cbs.tu-darmstadt.de>"]
|
||||||
license = "LGPL-3.0-only"
|
license = "LGPL-3.0-only"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
repository = "https://github.com/danijoo/xdrfile"
|
||||||
description = "Wrapper around the gromacs libxdrfile library. Can be used to read and write gromacs trajectories in xtc and trr format."
|
description = "Wrapper around the gromacs libxdrfile library. Can be used to read and write gromacs trajectories in xtc and trr format."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
categories = ["external-ffi-bindings", "encoding", "science"]
|
categories = ["external-ffi-bindings", "encoding", "science"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[](https://travis-ci.com/danijoo/xdrfile) [](https://www.crates.io/crates/xdrfile)
|
[](https://travis-ci.org/danijoo/xdrfile) [](https://www.crates.io/crates/xdrfile) [](https://docs.rs/xdrfile)
|
||||||
|
|
||||||
# xdrfile
|
# xdrfile
|
||||||
Read and write xdr trajectory files in .xtc and .trr file format
|
Read and write xdr trajectory files in .xtc and .trr file format
|
||||||
@@ -29,7 +29,7 @@ fn main() -> Result<()> {
|
|||||||
assert_eq!(frame.step, 1);
|
assert_eq!(frame.step, 1);
|
||||||
assert_eq!(frame.len(), num_atoms);
|
assert_eq!(frame.len(), num_atoms);
|
||||||
|
|
||||||
let first_atom_coords = frame.coords[0];
|
let first_atom_coords = frame[0]; // shorthand for frame.coords[0]
|
||||||
assert_eq!(first_atom_coords, [-0.8901, 0.4127, -0.055499997]);
|
assert_eq!(first_atom_coords, [-0.8901, 0.4127, -0.055499997]);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ impl std::error::Error for Error {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Error::CouldNotCheckNAtoms(err) => Some(err.as_ref()),
|
Error::CouldNotCheckNAtoms(err) => Some(err.as_ref()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ pub enum ErrorCode {
|
|||||||
|
|
||||||
impl ErrorCode {
|
impl ErrorCode {
|
||||||
/// True if the error is an end of file error, false otherwise
|
/// True if the error is an end of file error, false otherwise
|
||||||
pub fn is_eof(&self) -> bool {
|
pub fn is_eof(self) -> bool {
|
||||||
matches!(self, Self::ExdrEndOfFile)
|
matches!(self, Self::ExdrEndOfFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
89
src/frame.rs
89
src/frame.rs
@@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
/// A frame represents a single step in a trajectory.
|
/// A frame represents a single step in a trajectory.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
@@ -40,14 +42,13 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Filters the frame by removing all atoms not matching the given indeces.
|
/// Filters the frame by removing all atoms not matching the given indeces.
|
||||||
pub fn filter_coords(self: &mut Frame, indeces: &[usize]) {
|
pub fn filter_coords(self: &mut Frame, indices: &[usize]) {
|
||||||
self.coords = self
|
self.coords = self
|
||||||
.coords
|
.coords
|
||||||
.iter()
|
.iter()
|
||||||
.map(|elem| elem.clone())
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(i, _)| indeces.contains(&i))
|
.filter(|(i, _)| indices.contains(i))
|
||||||
.map(|(_, elem)| elem)
|
.map(|(_, elem)| *elem)
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +68,20 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Index<usize> for Frame {
|
||||||
|
type Output = [f32; 3];
|
||||||
|
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
&self.coords[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexMut<usize> for Frame {
|
||||||
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output { {
|
||||||
|
&mut self.coords[index]
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -81,15 +96,15 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_frame_filter_atoms() {
|
fn test_frame_filter_atoms() {
|
||||||
let mut frame = Frame::with_len(3);
|
let mut frame = Frame::with_len(3);
|
||||||
frame.coords[0] = [1.0, 2.0, 3.0];
|
frame[0] = [1.0, 2.0, 3.0];
|
||||||
frame.coords[1] = [4.0, 5.0, 6.0];
|
frame[1] = [4.0, 5.0, 6.0];
|
||||||
frame.coords[2] = [7.0, 8.0, 9.0];
|
frame[2] = [7.0, 8.0, 9.0];
|
||||||
let filter: Vec<usize> = vec![1, 2];
|
let filter: Vec<usize> = vec![1, 2];
|
||||||
let mut frame_new = frame.clone();
|
let mut frame_new = frame.clone();
|
||||||
frame_new.filter_coords(&filter);
|
frame_new.filter_coords(&filter);
|
||||||
assert!(frame_new.len() == filter.len());
|
assert!(frame_new.len() == filter.len());
|
||||||
assert!(frame_new.coords[0] == frame.coords[1]);
|
assert!(frame_new.coords[0] == frame[1]);
|
||||||
assert!(frame_new.coords[1] == frame.coords[2]);
|
assert!(frame_new.coords[1] == frame[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -97,4 +112,60 @@ mod tests {
|
|||||||
let frame = Frame::with_len(10);
|
let frame = Frame::with_len(10);
|
||||||
assert_eq!(frame.len(), 10);
|
assert_eq!(frame.len(), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_coords() {
|
||||||
|
let mut frame = Frame {
|
||||||
|
step: 0,
|
||||||
|
time: 0.0,
|
||||||
|
box_vector: [[0.0; 3]; 3],
|
||||||
|
coords: vec![[0.0; 3], [1.0; 3], [2.0; 3]]
|
||||||
|
};
|
||||||
|
|
||||||
|
frame.filter_coords(&[1]);
|
||||||
|
for i in 0..3 {
|
||||||
|
assert_approx_eq!(frame[0][i], 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
fn test_index() {
|
||||||
|
// test Index
|
||||||
|
let frame = Frame {
|
||||||
|
step: 0,
|
||||||
|
time: 0.0,
|
||||||
|
box_vector: [[0.0; 3]; 3],
|
||||||
|
coords: vec![[0.0; 3], [1.0; 3], [2.0; 3]]
|
||||||
|
};
|
||||||
|
for i in 0..frame.len() {
|
||||||
|
for j in 0..3 {
|
||||||
|
assert_approx_eq!(frame[i][j], frame[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test IndexMut
|
||||||
|
let mut frame = Frame {
|
||||||
|
step: 0,
|
||||||
|
time: 0.0,
|
||||||
|
box_vector: [[0.0; 3]; 3],
|
||||||
|
coords: vec![[0.0; 3], [1.0; 3], [2.0; 3]]
|
||||||
|
};
|
||||||
|
for i in 0..frame.len() {
|
||||||
|
for j in 0..3 {
|
||||||
|
assert_approx_eq!(frame[i][j], frame.coords[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame[0] = [123.0; 3];
|
||||||
|
for i in 0..frame.len() {
|
||||||
|
for j in 0..3 {
|
||||||
|
assert_approx_eq!(frame[i][j], frame.coords[i][j]);
|
||||||
|
if i == 0 {
|
||||||
|
assert_approx_eq!(frame[i][j], 123.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ impl<T: Trajectory> TrajectoryIterator<T> {
|
|||||||
// It's OK to do this every frame because the result is cached by Trajectory
|
// It's OK to do this every frame because the result is cached by Trajectory
|
||||||
let num_atoms = match &self.trajectory.get_num_atoms() {
|
let num_atoms = match &self.trajectory.get_num_atoms() {
|
||||||
&Ok(n) => n,
|
&Ok(n) => n,
|
||||||
Err(e) => Err(Error::CouldNotCheckNAtoms(Box::new(e.clone())))?,
|
Err(e) => return Err(Error::CouldNotCheckNAtoms(Box::new(e.clone()))),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reuse old frame
|
// Reuse old frame
|
||||||
|
|||||||
113
src/lib.rs
113
src/lib.rs
@@ -26,7 +26,7 @@
|
|||||||
//! assert_eq!(frame.step, 1);
|
//! assert_eq!(frame.step, 1);
|
||||||
//! assert_eq!(frame.len(), num_atoms);
|
//! assert_eq!(frame.len(), num_atoms);
|
||||||
//!
|
//!
|
||||||
//! let first_atom_coords = frame.coords[0];
|
//! let first_atom_coords = frame[0];
|
||||||
//! assert_eq!(first_atom_coords, [-0.8901, 0.4127, -0.055499997]);
|
//! assert_eq!(first_atom_coords, [-0.8901, 0.4127, -0.055499997]);
|
||||||
//!
|
//!
|
||||||
//! Ok(())
|
//! Ok(())
|
||||||
@@ -175,7 +175,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((path, filemode))?
|
Err((path, filemode).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,6 +232,7 @@ pub trait Trajectory {
|
|||||||
|
|
||||||
/// 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<usize>;
|
fn get_num_atoms(&mut self) -> Result<usize>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle to Read/Write XTC Trajectories
|
/// Handle to Read/Write XTC Trajectories
|
||||||
@@ -275,8 +276,8 @@ impl Trajectory for XTCTrajectory {
|
|||||||
.get_num_atoms()
|
.get_num_atoms()
|
||||||
.map_err(|e| Error::CouldNotCheckNAtoms(Box::new(e)))?;
|
.map_err(|e| Error::CouldNotCheckNAtoms(Box::new(e)))?;
|
||||||
if num_atoms != frame.coords.len() {
|
if num_atoms != frame.coords.len() {
|
||||||
Err((&*frame, num_atoms))?;
|
return Err((&*frame, num_atoms).into());
|
||||||
};
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let code = xdrfile_xtc::read_xtc(
|
let code = xdrfile_xtc::read_xtc(
|
||||||
@@ -402,7 +403,7 @@ impl Trajectory for TRRTrajectory {
|
|||||||
.get_num_atoms()
|
.get_num_atoms()
|
||||||
.map_err(|e| Error::CouldNotCheckNAtoms(Box::new(e)))?;
|
.map_err(|e| Error::CouldNotCheckNAtoms(Box::new(e)))?;
|
||||||
if num_atoms != frame.coords.len() {
|
if num_atoms != frame.coords.len() {
|
||||||
Err((&*frame, num_atoms))?;
|
return Err((&*frame, num_atoms).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -501,14 +502,15 @@ mod tests {
|
|||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_write_xtc() -> Result<()> {
|
fn test_write_append_read_xtc() -> Result<()> {
|
||||||
let tempfile = NamedTempFile::new().expect("Could not create temporary file");
|
let tempfile = NamedTempFile::new().expect("Could not create temporary file");
|
||||||
let tmp_path = tempfile.path();
|
let tmp_path = tempfile.path();
|
||||||
|
|
||||||
let natoms = 2;
|
let natoms = 2;
|
||||||
|
|
||||||
|
// write frame 1
|
||||||
let frame = Frame {
|
let frame = Frame {
|
||||||
step: 5,
|
step: 1,
|
||||||
time: 2.0,
|
time: 1.0,
|
||||||
box_vector: [[1.0, 2.0, 3.0], [2.0, 1.0, 3.0], [3.0, 2.0, 1.0]],
|
box_vector: [[1.0, 2.0, 3.0], [2.0, 1.0, 3.0], [3.0, 2.0, 1.0]],
|
||||||
coords: vec![[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]],
|
coords: vec![[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]],
|
||||||
};
|
};
|
||||||
@@ -520,11 +522,28 @@ mod tests {
|
|||||||
}
|
}
|
||||||
f.flush()?;
|
f.flush()?;
|
||||||
|
|
||||||
|
// append frame 2
|
||||||
|
let frame2 = Frame {
|
||||||
|
step: 2,
|
||||||
|
time: 2.0,
|
||||||
|
box_vector: [[1.0, 2.0, 3.0], [2.0, 1.0, 3.0], [3.0, 2.0, 1.0]],
|
||||||
|
coords: vec![[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]],
|
||||||
|
};
|
||||||
|
let mut f = XTCTrajectory::open_append(&tmp_path)?;
|
||||||
|
let write_status = f.write(&frame2);
|
||||||
|
match write_status {
|
||||||
|
Err(_) => panic!("Failed"),
|
||||||
|
Ok(()) => {}
|
||||||
|
}
|
||||||
|
f.flush()?;
|
||||||
|
|
||||||
|
// open trj for read
|
||||||
let mut new_frame = Frame::with_len(natoms);
|
let mut new_frame = Frame::with_len(natoms);
|
||||||
let mut f = XTCTrajectory::open_read(tmp_path)?;
|
let mut f = XTCTrajectory::open_read(tmp_path)?;
|
||||||
let num_atoms = f.get_num_atoms()?;
|
let num_atoms = f.get_num_atoms()?;
|
||||||
assert_eq!(num_atoms, natoms);
|
assert_eq!(num_atoms, natoms);
|
||||||
|
|
||||||
|
// check frame 1 ...
|
||||||
let read_status = f.read(&mut new_frame);
|
let read_status = f.read(&mut new_frame);
|
||||||
match read_status {
|
match read_status {
|
||||||
Err(e) => assert!(false, "{:?}", e),
|
Err(e) => assert!(false, "{:?}", e),
|
||||||
@@ -536,22 +555,36 @@ mod tests {
|
|||||||
assert_approx_eq!(new_frame.time, frame.time);
|
assert_approx_eq!(new_frame.time, frame.time);
|
||||||
assert_eq!(new_frame.box_vector, frame.box_vector);
|
assert_eq!(new_frame.box_vector, frame.box_vector);
|
||||||
assert_eq!(new_frame.coords, frame.coords);
|
assert_eq!(new_frame.coords, frame.coords);
|
||||||
|
|
||||||
|
// and check frame 1 ...
|
||||||
|
let read_status = f.read(&mut new_frame);
|
||||||
|
match read_status {
|
||||||
|
Err(e) => assert!(false, "{:?}", e),
|
||||||
|
Ok(()) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(new_frame.len(), frame2.len());
|
||||||
|
assert_eq!(new_frame.step, frame2.step);
|
||||||
|
assert_approx_eq!(new_frame.time, frame2.time);
|
||||||
|
assert_eq!(new_frame.box_vector, frame2.box_vector);
|
||||||
|
assert_eq!(new_frame.coords, frame2.coords);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_write_trr() -> Result<()> {
|
fn test_write_append_read_trr() -> Result<()> {
|
||||||
let tempfile = NamedTempFile::new().expect("Could not create temporary file");
|
let tempfile = NamedTempFile::new().expect("Could not create temporary file");
|
||||||
let tmp_path = tempfile.path();
|
let tmp_path = tempfile.path();
|
||||||
|
|
||||||
let natoms = 2;
|
let natoms = 2;
|
||||||
|
|
||||||
|
// write frame 1
|
||||||
let frame = Frame {
|
let frame = Frame {
|
||||||
step: 5,
|
step: 1,
|
||||||
time: 2.0,
|
time: 1.0,
|
||||||
box_vector: [[1.0, 2.0, 3.0], [2.0, 1.0, 3.0], [3.0, 2.0, 1.0]],
|
box_vector: [[1.0, 2.0, 3.0], [2.0, 1.0, 3.0], [3.0, 2.0, 1.0]],
|
||||||
coords: vec![[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]],
|
coords: vec![[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]],
|
||||||
};
|
};
|
||||||
let mut f = TRRTrajectory::open_write(tmp_path)?;
|
let mut f = TRRTrajectory::open_write(&tmp_path)?;
|
||||||
let write_status = f.write(&frame);
|
let write_status = f.write(&frame);
|
||||||
match write_status {
|
match write_status {
|
||||||
Err(_) => panic!("Failed"),
|
Err(_) => panic!("Failed"),
|
||||||
@@ -559,11 +592,28 @@ mod tests {
|
|||||||
}
|
}
|
||||||
f.flush()?;
|
f.flush()?;
|
||||||
|
|
||||||
|
// append frame 2
|
||||||
|
let frame2 = Frame {
|
||||||
|
step: 2,
|
||||||
|
time: 2.0,
|
||||||
|
box_vector: [[1.0, 2.0, 3.0], [2.0, 1.0, 3.0], [3.0, 2.0, 1.0]],
|
||||||
|
coords: vec![[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]],
|
||||||
|
};
|
||||||
|
let mut f = TRRTrajectory::open_append(&tmp_path)?;
|
||||||
|
let write_status = f.write(&frame2);
|
||||||
|
match write_status {
|
||||||
|
Err(_) => panic!("Failed"),
|
||||||
|
Ok(()) => {}
|
||||||
|
}
|
||||||
|
f.flush()?;
|
||||||
|
|
||||||
|
// open trj for read
|
||||||
let mut new_frame = Frame::with_len(natoms);
|
let mut new_frame = Frame::with_len(natoms);
|
||||||
let mut f = TRRTrajectory::open_read(tmp_path)?;
|
let mut f = TRRTrajectory::open_read(tmp_path)?;
|
||||||
// let num_atoms = f.get_num_atoms()?;
|
let num_atoms = f.get_num_atoms()?;
|
||||||
// assert_eq!(num_atoms, natoms);
|
assert_eq!(num_atoms, natoms);
|
||||||
|
|
||||||
|
// check frame 1 ...
|
||||||
let read_status = f.read(&mut new_frame);
|
let read_status = f.read(&mut new_frame);
|
||||||
match read_status {
|
match read_status {
|
||||||
Err(e) => assert!(false, "{:?}", e),
|
Err(e) => assert!(false, "{:?}", e),
|
||||||
@@ -572,9 +622,22 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(new_frame.len(), frame.len());
|
assert_eq!(new_frame.len(), frame.len());
|
||||||
assert_eq!(new_frame.step, frame.step);
|
assert_eq!(new_frame.step, frame.step);
|
||||||
assert_eq!(new_frame.time, frame.time);
|
assert_approx_eq!(new_frame.time, frame.time);
|
||||||
assert_eq!(new_frame.box_vector, frame.box_vector);
|
assert_eq!(new_frame.box_vector, frame.box_vector);
|
||||||
assert_eq!(new_frame.coords, frame.coords);
|
assert_eq!(new_frame.coords, frame.coords);
|
||||||
|
|
||||||
|
// and check frame 1 ...
|
||||||
|
let read_status = f.read(&mut new_frame);
|
||||||
|
match read_status {
|
||||||
|
Err(e) => assert!(false, "{:?}", e),
|
||||||
|
Ok(()) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(new_frame.len(), frame2.len());
|
||||||
|
assert_eq!(new_frame.step, frame2.step);
|
||||||
|
assert_approx_eq!(new_frame.time, frame2.time);
|
||||||
|
assert_eq!(new_frame.box_vector, frame2.box_vector);
|
||||||
|
assert_eq!(new_frame.coords, frame2.coords);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,21 +694,17 @@ mod tests {
|
|||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
assert_eq!(s, CString::new("test")?);
|
assert_eq!(s, CString::new("test")?);
|
||||||
}
|
}
|
||||||
Err(_) => panic!("Valid Path failed to convert to CString.")
|
Err(_) => panic!("Valid Path failed to convert to CString."),
|
||||||
}
|
}
|
||||||
|
|
||||||
// \0 in path should result in an InvalidOsStr(Some(NulError))
|
// \0 in path should result in an InvalidOsStr(Some(NulError))
|
||||||
let result = path_to_cstring(PathBuf::from("invalid/\0path"));
|
let result = path_to_cstring(PathBuf::from("invalid/\0path"));
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => panic!("Cstring conversion did not fail"),
|
Ok(_) => panic!("Cstring conversion did not fail"),
|
||||||
Err(e) => {
|
Err(e) => match e {
|
||||||
match e {
|
Error::InvalidOsStr(opt) => assert!(opt.is_some()),
|
||||||
Error::InvalidOsStr(opt) => {
|
_ => panic!("Wrong error type. (This should never happend)."),
|
||||||
assert!(opt.is_some())
|
},
|
||||||
}
|
|
||||||
_ => panic!("Wrong error type. (This should never happend).")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user