Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ serde = { version = "1.0.203", features = ["derive"] }
serde-xml-rs = "0.6.0"
serde_json = "1.0.117"
thiserror = "1.0.61"

[dev-dependencies]
tempfile = "3.10.1"
10 changes: 7 additions & 3 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ use thiserror::Error;
#[non_exhaustive]
pub enum Error {
/// The file is not a XML file.
#[error("File is not a XML file.")]
InvalidFileType,
#[error("File {:?} is not a XML file.", 0)]
InvalidFileType(PathBuf),

/// The file was not found at the specififed path.
#[error("File was not found at the specified path: {:?}.", 0)]
FileNotFound(PathBuf),

/// An unknown error occurred.
/// An io error occurred.
#[error(transparent)]
IO(#[from] std::io::Error),

/// A parsing error occurred.
#[error(transparent)]
ParsingError(#[from] serde_xml_rs::Error),

/// An unknown error occurred.
#[error("Unknown error")]
Unknown,
}
97 changes: 88 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ use crate::native::{
/// assert!(native.sites.len() >= 1, "Vector length is less than 1");
/// ```
pub fn parse_site_native_file(xml_path: &Path) -> Result<SiteNative, Error> {
if !xml_path.exists() {
return Err(Error::FileNotFound(xml_path.to_path_buf()));
}
check_valid_xml_file(xml_path)?;

let xml_file = read_to_string(xml_path)?;
let native = parse_site_native_string(&xml_file)?;
Expand Down Expand Up @@ -406,9 +404,7 @@ pub fn parse_site_native_string(xml_str: &str) -> Result<SiteNative, Error> {
/// assert!(native.patients.len() >= 1, "Vector length is less than 1");
/// ```
pub fn parse_subject_native_file(xml_path: &Path) -> Result<SubjectNative, Error> {
if !xml_path.exists() {
return Err(Error::FileNotFound(xml_path.to_path_buf()));
}
check_valid_xml_file(xml_path)?;

let xml_file = read_to_string(xml_path)?;
let native = parse_subject_native_string(&xml_file)?;
Expand Down Expand Up @@ -617,9 +613,7 @@ pub fn parse_subject_native_string(xml_str: &str) -> Result<SubjectNative, Error
/// assert!(native.users.len() >= 1, "Vector length is less than 1");
/// ```
pub fn parse_user_native_file(xml_path: &Path) -> Result<UserNative, Error> {
if !xml_path.exists() {
return Err(Error::FileNotFound(xml_path.to_path_buf()));
}
check_valid_xml_file(xml_path)?;

let xml_file = read_to_string(xml_path)?;
let native = parse_user_native_string(&xml_file)?;
Expand Down Expand Up @@ -792,3 +786,88 @@ pub fn parse_user_native_string(xml_str: &str) -> Result<UserNative, Error> {

Ok(native)
}

fn check_valid_xml_file(xml_path: &Path) -> Result<(), Error> {
if !xml_path.exists() {
return Err(Error::FileNotFound(xml_path.to_path_buf()));
}

if let Some(extension) = xml_path.extension() {
if extension != "xml" {
return Err(Error::InvalidFileType(xml_path.to_owned()));
}
} else {
return Err(Error::Unknown);
}

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use tempfile::{tempdir, Builder};

#[test]
fn test_site_file_not_found_error() {
let dir = tempdir().unwrap().path().to_path_buf();
let result = parse_site_native_file(&dir);
assert!(result.is_err());
assert!(matches!(result, Err(Error::FileNotFound(_))));
}

#[test]
fn test_site_invaid_file_type_error() {
let file = Builder::new()
.prefix("test")
.suffix(".csv")
.tempfile()
.unwrap();
let result = parse_site_native_file(file.path());

assert!(result.is_err());
assert!(matches!(result, Err(Error::InvalidFileType(_))));
}

#[test]
fn test_subject_file_not_found_error() {
let dir = tempdir().unwrap().path().to_path_buf();
let result = parse_subject_native_file(&dir);
assert!(result.is_err());
assert!(matches!(result, Err(Error::FileNotFound(_))));
}

#[test]
fn test_subject_invaid_file_type_error() {
let file = Builder::new()
.prefix("test")
.suffix(".csv")
.tempfile()
.unwrap();
let result = parse_subject_native_file(file.path());

assert!(result.is_err());
assert!(matches!(result, Err(Error::InvalidFileType(_))));
}

#[test]
fn test_user_file_not_found_error() {
let dir = tempdir().unwrap().path().to_path_buf();
let result = parse_user_native_file(&dir);
assert!(result.is_err());
assert!(matches!(result, Err(Error::FileNotFound(_))));
}

#[test]
fn test_user_invaid_file_type_error() {
let file = Builder::new()
.prefix("test")
.suffix(".csv")
.tempfile()
.unwrap();
let result = parse_user_native_file(file.path());

assert!(result.is_err());
assert!(matches!(result, Err(Error::InvalidFileType(_))));
}
}