diff --git a/src/native/site_native.rs b/src/native/site_native.rs index 5c4fe50..91bf8a8 100644 --- a/src/native/site_native.rs +++ b/src/native/site_native.rs @@ -2,6 +2,7 @@ use chrono::{DateTime, Utc}; #[cfg(feature = "python")] use pyo3::{ + exceptions::PyValueError, prelude::*, types::{PyDateTime, PyDict}, }; @@ -133,6 +134,32 @@ pub struct SiteNative { pub sites: Vec, } +#[cfg(not(feature = "python"))] +impl SiteNative { + /// Convert to a JSON string + /// + /// # Example + /// + /// ``` + /// use std::path::Path; + /// + /// use prelude_xml_parser::parse_site_native_file; + /// + /// let file_path = Path::new("tests/assets/site_native_small.xml"); + /// let native = parse_site_native_file(&file_path).unwrap(); + /// let json = native.to_json().unwrap(); + /// println!("{json}"); + /// let expected = r#"{"sites":[{"name":"Some Site","uniqueId":"1681574834910","numberOfPatients":4,"countOfRandomizedPatients":0,"whenCreated":"2023-04-15T16:08:19Z","creator":"Paul Sanders","numberOfForms":1,"forms":[{"name":"demographic.form.name.site.demographics","lastModified":"2023-04-15T16:08:19Z","whoLastModifiedName":"Paul Sanders","whoLastModifiedRole":"Project Manager","whenCreated":1681574834930,"hasErrors":false,"hasWarnings":false,"locked":false,"user":null,"dateTimeChanged":null,"formTitle":"Site Demographics","formIndex":1,"formGroup":"Demographic","formState":"In-Work","states":[{"value":"form.state.in.work","signer":"Paul Sanders - Project Manager","signerUniqueId":"1681162687395","dateSigned":"2023-04-15T16:08:19Z"}],"categories":[{"name":"Demographics","categoryType":"normal","highestIndex":0,"fields":[{"name":"address","fieldType":"text","dataType":"string","errorCode":"valid","whenCreated":"2023-04-15T16:07:14Z","keepHistory":true,"entries":null,"comments":null},{"name":"company","fieldType":"text","dataType":"string","errorCode":"valid","whenCreated":"2023-04-15T16:07:14Z","keepHistory":true,"entries":[{"entryId":"1","value":{"by":"Paul Sanders","byUniqueId":"1681162687395","role":"Project Manager","when":"2023-04-15T16:08:19Z","value":"Some Company"},"reason":null}],"comments":[{"commentId":"1","value":{"by":"Paul Sanders","byUniqueId":"1681162687395","role":"Project Manager","when":"2023-04-15T16:09:02Z","value":"Some Comment"}}]}]}]}]}]}"#;; + /// + /// assert_eq!(json, expected); + /// ``` + pub fn to_json(&self) -> serde_json::Result { + let json = serde_json::to_string(&self)?; + + Ok(json) + } +} + #[cfg(feature = "python")] /// Contains the information from the Prelude native site XML. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -162,6 +189,12 @@ impl SiteNative { dict.set_item("sites", site_dicts)?; Ok(dict) } + + /// Convert the class instance to a JSON string + fn to_json(&self) -> PyResult { + serde_json::to_string(&self) + .map_err(|_| PyErr::new::("Error converting to JSON")) + } } #[cfg(test)] diff --git a/src/native/subject_native.rs b/src/native/subject_native.rs index 0f5e4f7..a05f220 100644 --- a/src/native/subject_native.rs +++ b/src/native/subject_native.rs @@ -2,6 +2,7 @@ use chrono::{DateTime, Utc}; #[cfg(feature = "python")] use pyo3::{ + exceptions::PyValueError, prelude::*, types::{PyDateTime, PyDict}, }; @@ -149,6 +150,31 @@ pub struct SubjectNative { pub patients: Vec, } +#[cfg(not(feature = "python"))] +impl SubjectNative { + /// Convert to a JSON string + /// + /// # Example + /// + /// ``` + /// use std::path::Path; + /// + /// use prelude_xml_parser::parse_subject_native_file; + /// + /// let file_path = Path::new("tests/assets/subject_native_small.xml"); + /// let native = parse_subject_native_file(&file_path).unwrap(); + /// let expected = r#"{"patients":[{"patientId":"ABC-001","uniqueId":"1681574905819","whenCreated":"2023-04-15T16:09:02Z","creator":"Paul Sanders","siteName":"Some Site","siteUniqueId":"1681574834910","lastLanguage":null,"numberOfForms":6,"forms":[{"name":"day.0.form.name.demographics","lastModified":"2023-04-15T16:09:15Z","whoLastModifiedName":"Paul Sanders","whoLastModifiedRole":"Project Manager","whenCreated":1681574905839,"hasErrors":false,"hasWarnings":false,"locked":false,"user":null,"dateTimeChanged":null,"formTitle":"Demographics","formIndex":1,"formGroup":"Day 0","formState":"In-Work","states":[{"value":"form.state.in.work","signer":"Paul Sanders - Project Manager","signerUniqueId":"1681162687395","dateSigned":"2023-04-15T16:09:02Z"}],"categories":[{"name":"Demographics","categoryType":"normal","highestIndex":0,"fields":[{"name":"breed","fieldType":"combo-box","dataType":"string","errorCode":"valid","whenCreated":"2023-04-15T16:08:26Z","keepHistory":true,"entries":[{"entryId":"1","value":{"by":"Paul Sanders","byUniqueId":"1681162687395","role":"Project Manager","when":"2023-04-15T16:09:02Z","value":"Labrador"},"reason":null}],"comments":[{"commentId":"1","value":{"by":"Paul Sanders","byUniqueId":"1681162687395","role":"Project Manager","when":"2023-04-15T16:09:02Z","value":"Some Comment"}}]}]}]}]}]}"#; + /// let json = native.to_json().unwrap(); + /// + /// assert_eq!(json, expected); + /// ``` + pub fn to_json(&self) -> serde_json::Result { + let json = serde_json::to_string(&self)?; + + Ok(json) + } +} + #[cfg(feature = "python")] /// Contains the information from the Prelude native subject XML. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -178,6 +204,12 @@ impl SubjectNative { dict.set_item("patients", patient_dicts)?; Ok(dict) } + + /// Convert the class instance to a JSON string + fn to_json(&self) -> PyResult { + serde_json::to_string(&self) + .map_err(|_| PyErr::new::("Error converting to JSON")) + } } #[cfg(test)] diff --git a/src/native/user_native.rs b/src/native/user_native.rs index e6aa3f8..c9a3917 100644 --- a/src/native/user_native.rs +++ b/src/native/user_native.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "python")] -use pyo3::{prelude::*, types::PyDict}; +use pyo3::{exceptions::PyValueError, prelude::*, types::PyDict}; pub use crate::native::{ common::{Category, Comment, Entry, Field, Form, Reason, State, Value}, @@ -102,6 +102,31 @@ pub struct UserNative { pub users: Vec, } +#[cfg(not(feature = "python"))] +impl UserNative { + /// Convert to a JSON string + /// + /// # Example + /// + /// ``` + /// use std::path::Path; + /// + /// use prelude_xml_parser::parse_user_native_file; + /// + /// let file_path = Path::new("tests/assets/user_native_small.xml"); + /// let native = parse_user_native_file(&file_path).unwrap(); + /// let expected = r#"{"users":[{"uniqueId":"1691421275437","lastLanguage":null,"creator":"Paul Sanders(1681162687395)","numberOfForms":1,"forms":[{"name":"form.name.demographics","lastModified":"2023-08-07T15:15:41Z","whoLastModifiedName":"Paul Sanders","whoLastModifiedRole":"Project Manager","whenCreated":1691421341578,"hasErrors":false,"hasWarnings":false,"locked":false,"user":null,"dateTimeChanged":null,"formTitle":"User Demographics","formIndex":1,"formGroup":null,"formState":"In-Work","states":[{"value":"form.state.in.work","signer":"Paul Sanders - Project Manager","signerUniqueId":"1681162687395","dateSigned":"2023-08-07T15:15:41Z"}],"categories":[{"name":"demographics","categoryType":"normal","highestIndex":0,"fields":[{"name":"address","fieldType":"text","dataType":"string","errorCode":"undefined","whenCreated":"2024-01-12T20:14:09Z","keepHistory":true,"entries":null,"comments":null},{"name":"email","fieldType":"text","dataType":"string","errorCode":"undefined","whenCreated":"2023-08-07T15:15:41Z","keepHistory":true,"entries":[{"entryId":"1","value":{"by":"Paul Sanders","byUniqueId":"1681162687395","role":"Project Manager","when":"2023-08-07T15:15:41Z","value":"jazz@artemis.com"},"reason":null}],"comments":[{"commentId":"1","value":{"by":"Paul Sanders","byUniqueId":"1681162687395","role":"Project Manager","when":"2023-04-15T16:09:02Z","value":"Some Comment"}}]}]},{"name":"Administrative","categoryType":"normal","highestIndex":0,"fields":[{"name":"study_assignment","fieldType":"text","dataType":null,"errorCode":"undefined","whenCreated":"2023-08-07T15:15:41Z","keepHistory":true,"entries":[{"entryId":"1","value":{"by":"set from calculation","byUniqueId":null,"role":"System","when":"2023-08-07T15:15:41Z","value":"On 07-Aug-2023 10:15 -0500, Paul Sanders assigned user from another study"},"reason":{"by":"set from calculation","byUniqueId":null,"role":"System","when":"2023-08-07T15:15:41Z","value":"calculated value"}}],"comments":null}]}]}]},{"uniqueId":"1681162687395","lastLanguage":null,"creator":"1609858291483(1609858291483)","numberOfForms":2,"forms":[{"name":"form.name.demographics","lastModified":"2023-04-10T21:39:30Z","whoLastModifiedName":"1609858291483","whoLastModifiedRole":"role.administrator","whenCreated":1681162770378,"hasErrors":false,"hasWarnings":false,"locked":false,"user":null,"dateTimeChanged":null,"formTitle":"User Demographics","formIndex":1,"formGroup":null,"formState":"In-Work","states":[{"value":"form.state.in.work","signer":"1609858291483 - Administrator","signerUniqueId":"1609858291483","dateSigned":"2023-04-10T21:39:30Z"}],"categories":[{"name":"demographics","categoryType":"normal","highestIndex":0,"fields":[{"name":"address","fieldType":"text","dataType":"string","errorCode":"undefined","whenCreated":"2023-04-15T15:21:14Z","keepHistory":true,"entries":null,"comments":null},{"name":"email","fieldType":"text","dataType":"string","errorCode":"undefined","whenCreated":"2023-04-10T21:39:30Z","keepHistory":true,"entries":[{"entryId":"1","value":{"by":"1609858291483","byUniqueId":"1609858291483","role":"Administrator","when":"2023-04-10T21:39:30Z","value":"paul@pbsdatasolutions.com"},"reason":null}],"comments":null}]},{"name":"Administrative","categoryType":"normal","highestIndex":0,"fields":[{"name":"study_assignment","fieldType":"text","dataType":null,"errorCode":"undefined","whenCreated":"2023-04-10T21:39:30Z","keepHistory":true,"entries":[{"entryId":"1","value":{"by":"set from calculation","byUniqueId":null,"role":"System","when":"2023-04-10T21:39:30Z","value":"On 10-Apr-2023 16:39 -0500, 1609858291483 assigned user from another study"},"reason":{"by":"set from calculation","byUniqueId":null,"role":"System","when":"2023-04-10T21:39:30Z","value":"calculated value"}}],"comments":null}]}]},{"name":"training.form.name.checklist","lastModified":null,"whoLastModifiedName":null,"whoLastModifiedRole":null,"whenCreated":1702998014133,"hasErrors":false,"hasWarnings":false,"locked":false,"user":null,"dateTimeChanged":null,"formTitle":"Training Checklist","formIndex":1,"formGroup":"Training","formState":"New","states":[{"value":"form.state.new","signer":"System set","signerUniqueId":"system","dateSigned":"2023-12-19T15:00:14Z"}],"categories":[{"name":"Training_Modules","categoryType":"normal","highestIndex":0,"fields":[{"name":"date(1)","fieldType":"setToday","dataType":"date","errorCode":"undefined","whenCreated":"2023-12-19T15:00:15Z","keepHistory":true,"entries":null,"comments":null}]},{"name":"Other_Training_Modules","categoryType":"indexed","highestIndex":1,"fields":[{"name":"date_field(1)","fieldType":"setToday","dataType":"date","errorCode":"undefined","whenCreated":"2023-12-19T15:00:15Z","keepHistory":true,"entries":null,"comments":null}]},{"name":"21CFR11","categoryType":"normal","highestIndex":0,"fields":null}]}]}]}"#; + /// let json = native.to_json().unwrap(); + /// + /// assert_eq!(json, expected); + /// ``` + pub fn to_json(&self) -> serde_json::Result { + let json = serde_json::to_string(&self)?; + + Ok(json) + } +} + #[cfg(feature = "python")] /// Contains the information from the Prelude native user XML. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -131,6 +156,12 @@ impl UserNative { dict.set_item("users", user_dicts)?; Ok(dict) } + + /// Convert the class instance to a JSON string + fn to_json(&self) -> PyResult { + serde_json::to_string(&self) + .map_err(|_| PyErr::new::("Error converting to JSON")) + } } #[cfg(test)] diff --git a/tests/assets/site_native_small.xml b/tests/assets/site_native_small.xml new file mode 100644 index 0000000..e5c6620 --- /dev/null +++ b/tests/assets/site_native_small.xml @@ -0,0 +1,21 @@ + + + + +
+ + + + + + Some Company + + + Some Comment + + + + +
+ +
diff --git a/tests/assets/subject_native_small.xml b/tests/assets/subject_native_small.xml new file mode 100644 index 0000000..6fe5259 --- /dev/null +++ b/tests/assets/subject_native_small.xml @@ -0,0 +1,20 @@ + + + + +
+ + + + + Labrador + + + Some Comment + + + + +
+ +
diff --git a/tests/assets/user_native_small.xml b/tests/assets/user_native_small.xml new file mode 100644 index 0000000..064ac05 --- /dev/null +++ b/tests/assets/user_native_small.xml @@ -0,0 +1,61 @@ + + + + +
+ + + + + + jazz@artemis.com + + + Some Comment + + + + + + + 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 + + + + +
+ + + + + + + + + +
+ +