diff --git a/prelude_parser/__init__.py b/prelude_parser/__init__.py index b6d90d3..804ce93 100644 --- a/prelude_parser/__init__.py +++ b/prelude_parser/__init__.py @@ -1,9 +1,14 @@ -from prelude_parser._prelude_parser import parse_site_native_file, parse_subject_native_file +from prelude_parser._prelude_parser import ( + parse_site_native_file, + parse_subject_native_file, + parse_user_native_file, +) from prelude_parser.parser import parse_to_classes, parse_to_dict __all__ = [ "parse_site_native_file", "parse_subject_native_file", + "parse_user_native_file", "parse_to_classes", "parse_to_dict", ] diff --git a/prelude_parser/_prelude_parser.pyi b/prelude_parser/_prelude_parser.pyi index b9d0541..1071e9a 100644 --- a/prelude_parser/_prelude_parser.pyi +++ b/prelude_parser/_prelude_parser.pyi @@ -2,7 +2,11 @@ from __future__ import annotations from pathlib import Path -from prelude_parser._prelude_parser import SiteNative, SubjectNative # type: ignore[attr-defined] +from prelude_parser._prelude_parser import ( # type: ignore[attr-defined] + SiteNative, + SubjectNative, + UserNative, +) from prelude_parser.types import FlatFormInfo def _parse_flat_file_to_dict( @@ -13,6 +17,7 @@ def _parse_flat_file_to_pandas_dict( ) -> dict[str, FlatFormInfo]: ... def parse_site_native_file(xml_file: str | Path) -> SiteNative: ... def parse_subject_native_file(xml_file: str | Path) -> SubjectNative: ... +def parse_user_native_file(xml_file: str | Path) -> UserNative: ... class FileNotFoundError(Exception): pass diff --git a/src/lib.rs b/src/lib.rs index 3cf3069..8cb51fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,9 +6,12 @@ use std::fs::read_to_string; use std::path::PathBuf; use chrono::{Datelike, NaiveDate}; -pub use prelude_xml_parser::native::{site_native::SiteNative, subject_native::SubjectNative}; +pub use prelude_xml_parser::native::{ + site_native::SiteNative, subject_native::SubjectNative, user_native::UserNative, +}; use prelude_xml_parser::parse_site_native_file as parse_site_native_file_rs; use prelude_xml_parser::parse_subject_native_file as parse_subject_native_file_rs; +use prelude_xml_parser::parse_user_native_file as parse_user_native_file_rs; use pyo3::prelude::*; use pyo3::types::{IntoPyDict, PyDict, PyList}; use roxmltree::Document; @@ -252,14 +255,27 @@ fn parse_subject_native_file(_py: Python, xml_file: PathBuf) -> PyResult PyResult { + match parse_user_native_file_rs(&xml_file) { + Ok(native) => Ok(native), + Err(e) => Err(ParsingError::new_err(format!( + "Error parsing xml file: {:?}", + e + ))), + } +} + #[pymodule] fn _prelude_parser(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; m.add_class::()?; + m.add_class::()?; m.add_function(wrap_pyfunction!(_parse_flat_file_to_dict, m)?)?; m.add_function(wrap_pyfunction!(_parse_flat_file_to_pandas_dict, m)?)?; m.add_function(wrap_pyfunction!(parse_site_native_file, m)?)?; m.add_function(wrap_pyfunction!(parse_subject_native_file, m)?)?; + m.add_function(wrap_pyfunction!(parse_user_native_file, m)?)?; m.add( "FileNotFoundError", py.get_type_bound::(), diff --git a/tests/assets/user_native.xml b/tests/assets/user_native.xml new file mode 100644 index 0000000..3ed934f --- /dev/null +++ b/tests/assets/user_native.xml @@ -0,0 +1,58 @@ + + + + +
+ + + + + + jazz@artemis.com + + + + + + + On 07-Aug-2023 10:15 -0500, Paul Sanders assigned user from another study + calculated value + + + + +
+ + +
+ + + + + + paul@pbsdatasolutions.com + + + + + + + On 10-Apr-2023 16:39 -0500, 1609858291483 assigned user from another study + calculated value + + + + +
+ + + + + + + + + +
+ +
diff --git a/tests/conftest.py b/tests/conftest.py index 9bbc5ff..7f117a5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -33,3 +33,8 @@ def site_native_xml(): @pytest.fixture def subject_native_xml(): return ASSETS_PATH / "subject_native.xml" + + +@pytest.fixture +def user_native_xml(): + return ASSETS_PATH / "user_native.xml" diff --git a/tests/test_parser.py b/tests/test_parser.py index 470cf56..920d5fd 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -7,6 +7,7 @@ parse_subject_native_file, parse_to_classes, parse_to_dict, + parse_user_native_file, ) from prelude_parser._prelude_parser import FileNotFoundError, InvalidFileTypeError, ParsingError @@ -23,6 +24,12 @@ def test_parse_subject_native(subject_native_xml): assert result.patients[0].patient_id == "ABC-001" +def test_parse_user_native(user_native_xml): + result = parse_user_native_file(user_native_xml) + + assert result.users[0].unique_id == "1691421275437" + + def test_parse_to_classes(test_file_1): result = parse_to_classes(test_file_1) assert len(result) == 2