diff --git a/Cargo.lock b/Cargo.lock index bcf155f..a42d6ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,7 @@ checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "prelude-xml-parser" -version = "0.7.1" +version = "0.7.2" dependencies = [ "chrono", "insta", diff --git a/Cargo.toml b/Cargo.toml index 7d97629..1f744e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prelude-xml-parser" -version = "0.7.1" +version = "0.7.2" edition = "2021" authors = ["Paul Sanders "] description = "Deserialize Prelude EDC native XML files into Rust stucts." diff --git a/src/lib.rs b/src/lib.rs index 4672759..e09dae9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,6 +86,9 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// /// 1111 Moon Drive /// +/// +/// Some comment +/// /// /// /// @@ -153,6 +156,7 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// .with_timezone(&Utc), /// keep_history: true, /// entries: None, +/// comments: None, /// }, /// Field { /// name: "company".to_string(), @@ -180,6 +184,7 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// }), /// reason: None, /// }]), +/// comments: None, /// }, /// Field { /// name: "site_code_name".to_string(), @@ -244,6 +249,7 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// }), /// }, /// ]), +/// comments: None, /// }, /// ]), /// }, @@ -264,6 +270,7 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// .with_timezone(&Utc), /// keep_history: true, /// entries: None, +/// comments: None, /// }, /// Field { /// name: "enrollment_open".to_string(), @@ -291,6 +298,7 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// }), /// reason: None, /// }]), +/// comments: None, /// }, /// Field { /// name: "enrollment_open_date".to_string(), @@ -304,6 +312,7 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// .with_timezone(&Utc), /// keep_history: true, /// entries: None, +/// comments: None, /// }, /// ]), /// }, @@ -375,6 +384,18 @@ pub fn parse_site_native_file(xml_path: &Path) -> Result { /// }), /// reason: None, /// }]), +/// comments: Some(vec![Comment { +/// comment_id: "1".to_string(), +/// value: Some(Value { +/// by: "Paul Sanders".to_string(), +/// by_unique_id: Some("1681162687395".to_string()), +/// role: "Project Manager".to_string(), +/// when: DateTime::parse_from_rfc3339("2023-08-07T15:14:21Z") +/// .unwrap() +/// .with_timezone(&Utc), +/// value: "Some comment".to_string(), +/// }), +/// }]), /// }]), /// }]), /// }]), @@ -515,6 +536,7 @@ pub fn parse_subject_native_file(xml_path: &Path) -> Result Result Result { /// .with_timezone(&Utc), /// keep_history: true, /// entries: None, +/// comments: None, /// }, /// Field { /// name: "email".to_string(), @@ -731,6 +755,7 @@ pub fn parse_user_native_file(xml_path: &Path) -> Result { /// }), /// reason: None, /// }]), +/// comments: None, /// }, /// ]), /// }, @@ -771,6 +796,7 @@ pub fn parse_user_native_file(xml_path: &Path) -> Result { /// }), /// }, /// ]), +/// comments: None, /// }, /// ]), /// }, diff --git a/src/native/common.rs b/src/native/common.rs index 40c4a06..460a149 100644 --- a/src/native/common.rs +++ b/src/native/common.rs @@ -228,6 +228,51 @@ impl Entry { } } +#[cfg(not(feature = "python"))] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct Comment { + #[serde(alias = "id")] + pub comment_id: String, + pub value: Option, +} + +#[cfg(feature = "python")] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "camelCase")] +#[pyclass(get_all)] +pub struct Comment { + #[serde(alias = "id")] + pub comment_id: String, + pub value: Option, +} + +#[cfg(feature = "python")] +#[pymethods] +impl Comment { + #[getter] + fn comment_id(&self) -> PyResult { + Ok(self.comment_id.clone()) + } + + #[getter] + fn value(&self) -> PyResult> { + Ok(self.value.clone()) + } + + pub fn to_dict<'py>(&self, py: Python<'py>) -> PyResult> { + let dict = PyDict::new_bound(py); + dict.set_item("comment_id", &self.comment_id)?; + if let Some(value) = &self.value { + dict.set_item("value", value.to_dict(py)?)?; + } else { + dict.set_item("value", py.None())?; + } + + Ok(dict) + } +} + #[cfg(not(feature = "python"))] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] #[serde(rename_all = "camelCase")] @@ -248,6 +293,9 @@ pub struct Field { #[serde(alias = "entry")] pub entries: Option>, + + #[serde(alias = "comment")] + pub comments: Option>, } #[cfg(feature = "python")] @@ -272,6 +320,9 @@ pub struct Field { #[serde(alias = "entry")] pub entries: Option>, + + #[serde(alias = "comment")] + pub comments: Option>, } #[cfg(feature = "python")] @@ -312,6 +363,11 @@ impl Field { Ok(self.entries.clone()) } + #[getter] + fn comments(&self) -> PyResult>> { + Ok(self.comments.clone()) + } + pub fn to_dict<'py>(&self, py: Python<'py>) -> PyResult> { let dict = PyDict::new_bound(py); dict.set_item("name", &self.name)?; @@ -332,6 +388,17 @@ impl Field { dict.set_item("entries", py.None())?; } + let mut comment_dicts = Vec::new(); + if let Some(comments) = &self.comments { + for comment in comments { + let comment_dict = comment.to_dict(py)?; + comment_dicts.push(comment_dict.to_object(py)); + } + dict.set_item("comments", comment_dicts)?; + } else { + dict.set_item("comments", py.None())?; + } + Ok(dict) } } diff --git a/src/native/site_native.rs b/src/native/site_native.rs index 3d94e02..16bb472 100644 --- a/src/native/site_native.rs +++ b/src/native/site_native.rs @@ -9,7 +9,7 @@ use pyo3::{ use serde::{Deserialize, Serialize}; pub use crate::native::{ - common::{Category, Entry, Field, Form, Reason, State, Value}, + common::{Category, Comment, Entry, Field, Form, Reason, State, Value}, deserializers::{ default_datetime_none, default_string_none, deserialize_empty_string_as_none, deserialize_empty_string_as_none_datetime, diff --git a/src/native/snapshots/prelude_xml_parser__native__site_native__tests__deserialize_site_native_json.snap b/src/native/snapshots/prelude_xml_parser__native__site_native__tests__deserialize_site_native_json.snap index 006ed40..d65a46f 100644 --- a/src/native/snapshots/prelude_xml_parser__native__site_native__tests__deserialize_site_native_json.snap +++ b/src/native/snapshots/prelude_xml_parser__native__site_native__tests__deserialize_site_native_json.snap @@ -42,6 +42,7 @@ sites: whenCreated: "2023-04-15T16:07:14Z" keepHistory: true entries: ~ + comments: ~ - name: company fieldType: text dataType: string @@ -57,6 +58,7 @@ sites: when: "2023-04-15T16:08:19Z" value: Some Company reason: ~ + comments: ~ - name: site_code_name fieldType: hidden dataType: string @@ -90,6 +92,7 @@ sites: role: System when: "2023-04-15T16:07:24Z" value: calculated value + comments: ~ - name: Enrollment categoryType: normal highestIndex: 0 @@ -101,6 +104,7 @@ sites: whenCreated: "2023-04-15T16:07:14Z" keepHistory: true entries: ~ + comments: ~ - name: enrollment_open fieldType: radio dataType: string @@ -116,6 +120,7 @@ sites: when: "2023-04-15T16:08:19Z" value: "Yes" reason: ~ + comments: ~ - name: enrollment_open_date fieldType: popUpCalendar dataType: date @@ -123,6 +128,7 @@ sites: whenCreated: "2023-04-15T16:07:14Z" keepHistory: true entries: ~ + comments: ~ - name: Artemis uniqueId: "1691420994591" numberOfPatients: 0 @@ -170,3 +176,4 @@ sites: when: "2023-08-07T15:14:21Z" value: 1111 Moon Drive reason: ~ + comments: ~ diff --git a/src/native/snapshots/prelude_xml_parser__native__subject_native__tests__deserialize_subject_native_json.snap b/src/native/snapshots/prelude_xml_parser__native__subject_native__tests__deserialize_subject_native_json.snap index 0cdefe3..22db3b7 100644 --- a/src/native/snapshots/prelude_xml_parser__native__subject_native__tests__deserialize_subject_native_json.snap +++ b/src/native/snapshots/prelude_xml_parser__native__subject_native__tests__deserialize_subject_native_json.snap @@ -51,6 +51,7 @@ patients: when: "2023-04-15T16:09:02Z" value: Labrador reason: ~ + comments: ~ - patientId: DEF-002 uniqueId: "1681574905820" whenCreated: "2023-04-16T16:10:02Z" @@ -99,3 +100,4 @@ patients: when: "2023-04-15T16:09:02Z" value: Labrador reason: ~ + comments: ~ diff --git a/src/native/snapshots/prelude_xml_parser__native__user_native__tests__deserialize_user_native_json.snap b/src/native/snapshots/prelude_xml_parser__native__user_native__tests__deserialize_user_native_json.snap index 69e0cb6..018d7ea 100644 --- a/src/native/snapshots/prelude_xml_parser__native__user_native__tests__deserialize_user_native_json.snap +++ b/src/native/snapshots/prelude_xml_parser__native__user_native__tests__deserialize_user_native_json.snap @@ -39,6 +39,7 @@ users: whenCreated: "2024-01-12T20:14:09Z" keepHistory: true entries: ~ + comments: ~ - name: email fieldType: text dataType: string @@ -54,6 +55,7 @@ users: when: "2023-08-07T15:15:41Z" value: jazz@artemis.com reason: ~ + comments: ~ - name: Administrative categoryType: normal highestIndex: 0 @@ -78,3 +80,4 @@ users: role: System when: "2023-08-07T15:15:41Z" value: calculated value + comments: ~ diff --git a/src/native/subject_native.rs b/src/native/subject_native.rs index 5ff7b2f..c81c55e 100644 --- a/src/native/subject_native.rs +++ b/src/native/subject_native.rs @@ -12,7 +12,7 @@ use crate::native::deserializers::to_py_datetime; use serde::{Deserialize, Serialize}; pub use crate::native::{ - common::{Category, Entry, Field, Form, Reason, State, Value}, + common::{Category, Comment, Entry, Field, Form, Reason, State, Value}, deserializers::{ default_datetime_none, default_string_none, deserialize_empty_string_as_none, deserialize_empty_string_as_none_datetime, diff --git a/src/native/user_native.rs b/src/native/user_native.rs index 38bb7c4..eaf11d1 100644 --- a/src/native/user_native.rs +++ b/src/native/user_native.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use pyo3::{prelude::*, types::PyDict}; pub use crate::native::{ - common::{Category, Entry, Field, Form, Reason, State, Value}, + common::{Category, Comment, Entry, Field, Form, Reason, State, Value}, deserializers::{ default_datetime_none, default_string_none, deserialize_empty_string_as_none, deserialize_empty_string_as_none_datetime, diff --git a/tests/assets/site_native.xml b/tests/assets/site_native.xml index bba945f..0d37994 100644 --- a/tests/assets/site_native.xml +++ b/tests/assets/site_native.xml @@ -10,6 +10,9 @@ Some Company + + Some Comment + diff --git a/tests/assets/subject_native.xml b/tests/assets/subject_native.xml index 9acaa79..b233a0b 100644 --- a/tests/assets/subject_native.xml +++ b/tests/assets/subject_native.xml @@ -9,6 +9,9 @@ Labrador + + Some Comment + diff --git a/tests/assets/user_native.xml b/tests/assets/user_native.xml index 3ed934f..064ac05 100644 --- a/tests/assets/user_native.xml +++ b/tests/assets/user_native.xml @@ -10,6 +10,9 @@ jazz@artemis.com + + Some Comment +