mirror of
https://github.com/dnlbauer/xdrfile.git
synced 2026-09-10 22:25:30 +00:00
single error type for cstring conversion
This commit is contained in:
@@ -14,9 +14,7 @@ pub enum Error {
|
|||||||
/// C API failed to open a file (No return code provided)
|
/// C API failed to open a file (No return code provided)
|
||||||
CouldNotOpen { path: PathBuf, mode: FileMode },
|
CouldNotOpen { path: PathBuf, mode: FileMode },
|
||||||
/// A path could not be converted to &OsStr
|
/// A path could not be converted to &OsStr
|
||||||
InvalidOsStr,
|
InvalidOsStr(Option<std::ffi::NulError>),
|
||||||
/// A path could not be converted to &CStr because it had a null byte
|
|
||||||
NullInStr(std::ffi::NulError),
|
|
||||||
/// Checking the number of atoms failed while reading a frame
|
/// Checking the number of atoms failed while reading a frame
|
||||||
CouldNotCheckNAtoms(Box<Error>),
|
CouldNotCheckNAtoms(Box<Error>),
|
||||||
/// Error for an out-of-range numeric conversion
|
/// Error for an out-of-range numeric conversion
|
||||||
@@ -61,7 +59,13 @@ impl std::error::Error for Error {
|
|||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
use Error::*;
|
use Error::*;
|
||||||
match &self {
|
match &self {
|
||||||
NullInStr(err) => Some(err),
|
InvalidOsStr(err) => {
|
||||||
|
if let Some(err) = err {
|
||||||
|
Some(err)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
CouldNotCheckNAtoms(err) => Some(err.as_ref()),
|
CouldNotCheckNAtoms(err) => Some(err.as_ref()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@@ -75,12 +79,6 @@ impl From<(ErrorCode, ErrorTask)> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::ffi::NulError> for Error {
|
|
||||||
fn from(err: std::ffi::NulError) -> Self {
|
|
||||||
Self::NullInStr(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(&Path, FileMode)> for Error {
|
impl From<(&Path, FileMode)> for Error {
|
||||||
fn from(value: (&Path, FileMode)) -> Self {
|
fn from(value: (&Path, FileMode)) -> Self {
|
||||||
let (path, mode) = value;
|
let (path, mode) = value;
|
||||||
@@ -119,9 +117,8 @@ impl std::fmt::Display for Error {
|
|||||||
CouldNotOpen { path, mode } => {
|
CouldNotOpen { path, mode } => {
|
||||||
write!(f, "Could not open file at {:?} in mode {:?}", path, mode)
|
write!(f, "Could not open file at {:?} in mode {:?}", path, mode)
|
||||||
}
|
}
|
||||||
InvalidOsStr => write!(f, "Paths must be valid unicode on this platform"),
|
InvalidOsStr(_) => write!(f, "Cannot convert path to CString."),
|
||||||
NullInStr(_err) => write!(f, "Paths cannot include null bytes"),
|
CouldNotCheckNAtoms(_) => {
|
||||||
CouldNotCheckNAtoms(_err) => {
|
|
||||||
write!(f, "Failed to read number of atoms in trajectory file")
|
write!(f, "Failed to read number of atoms in trajectory file")
|
||||||
}
|
}
|
||||||
OutOfRange {
|
OutOfRange {
|
||||||
@@ -249,8 +246,6 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::ffi::NulError;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_eof() {
|
fn test_is_eof() {
|
||||||
@@ -294,12 +289,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_correct_type() {
|
fn test_from_correct_type() {
|
||||||
let nul_err: NulError = CString::new(b"foo\0".to_vec()).unwrap_err();
|
|
||||||
let nul_err2: NulError = CString::new(b"foo\0".to_vec()).unwrap_err();
|
|
||||||
let err = Error::from(nul_err);
|
|
||||||
let expected = Error::NullInStr(nul_err2);
|
|
||||||
assert_eq!(expected, err);
|
|
||||||
|
|
||||||
let code = 3.into();
|
let code = 3.into();
|
||||||
let task = ErrorTask::Read;
|
let task = ErrorTask::Read;
|
||||||
let expected = Error::CApiError { code, task };
|
let expected = Error::CApiError { code, task };
|
||||||
|
|||||||
38
src/lib.rs
38
src/lib.rs
@@ -105,8 +105,11 @@ impl FileMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn path_to_cstring(path: impl AsRef<Path>) -> Result<CString> {
|
fn path_to_cstring(path: impl AsRef<Path>) -> Result<CString> {
|
||||||
let s = path.as_ref().to_str().ok_or(Error::InvalidOsStr)?;
|
if let Some(s) = path.as_ref().to_str() {
|
||||||
Ok(CString::new(s)?)
|
CString::new(s).map_err(|e| Error::InvalidOsStr(Some(e)))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidOsStr(None))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to<I, O>(value: I, task: ErrorTask, name: &'static str) -> Result<O>
|
fn to<I, O>(value: I, task: ErrorTask, name: &'static str) -> Result<O>
|
||||||
@@ -621,21 +624,28 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_path_to_cstring() -> Result<(), Box<dyn std::error::Error>> {
|
fn test_path_to_cstring() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let result_invalid = path_to_cstring(PathBuf::from("invalid/\0path"));
|
// A valid string should convert to CString successfully
|
||||||
|
let valid_result = path_to_cstring(PathBuf::from("test"));
|
||||||
if let Err(err) = result_invalid {
|
match valid_result {
|
||||||
match err {
|
Ok(s) => {
|
||||||
Error::NullInStr(_) => (),
|
assert_eq!(s, CString::new("test")?);
|
||||||
Error::InvalidOsStr => (),
|
|
||||||
_ => panic!("Improper error type for path_to_cstring"),
|
|
||||||
}
|
}
|
||||||
} else {
|
Err(_) => panic!("Valid Path failed to convert to CString.")
|
||||||
panic!("path_to_cstring should return Err if there are null bytes");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result_valid = path_to_cstring("valid/path");
|
// \0 in path should result in an InvalidOsStr(Some(NulError))
|
||||||
assert_eq!(result_valid, Ok(CString::new("valid/path")?));
|
let result = path_to_cstring(PathBuf::from("invalid/\0path"));
|
||||||
|
match result {
|
||||||
|
Ok(_) => panic!("Cstring conversion did not fail"),
|
||||||
|
Err(e) => {
|
||||||
|
match e {
|
||||||
|
Error::InvalidOsStr(opt) => {
|
||||||
|
assert!(opt.is_some())
|
||||||
|
}
|
||||||
|
_ => panic!("Wrong error type. (This should never happend).")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user