diff --git a/src/lkrexport.rs b/src/lkrexport.rs new file mode 100644 index 0000000..3c38d10 --- /dev/null +++ b/src/lkrexport.rs @@ -0,0 +1,167 @@ +/* + * This file is part of bzkf-rwdp-check + * + * Copyright (C) 2024 Comprehensive Cancer Center Mainfranken and contributors. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +use std::fs; +use std::path::Path; +use std::str::FromStr; + +use itertools::Itertools; +use regex::Regex; + +pub struct LkrExportProtocolFile { + pub patients: Vec, +} + +impl LkrExportProtocolFile { + pub fn parse_file(path: &Path) -> Result { + let xml_file_content = fs::read_to_string(path).map_err(|_| ())?; + Self::parse(&xml_file_content) + } + + pub fn parse(content: &str) -> Result { + let re = Regex::new(r"(?s)(?(.*?))").unwrap(); + + if re.is_match(content) { + let patients = re + .find_iter(content) + .map(|m| Patient { + raw_value: m.as_str().to_string(), + }) + .collect_vec(); + return Ok(LkrExportProtocolFile { patients }); + } + + Err(()) + } +} + +pub struct Patient { + pub raw_value: String, +} + +impl Patient { + pub fn meldungen(&self) -> Vec { + let re = Regex::new(r"(?s)(?)").unwrap(); + + if re.is_match(&self.raw_value) { + return re + .find_iter(&self.raw_value) + .map(|m| Meldung { + raw_value: m.as_str().to_string(), + }) + .collect_vec(); + } + vec![] + } +} + +pub struct Meldung { + pub raw_value: String, +} + +impl FromStr for Meldung { + type Err = (); + + fn from_str(s: &str) -> Result { + Ok(Meldung { + raw_value: s.to_string(), + }) + } +} + +impl Meldung { + pub fn id(&self) -> Option { + let re = Regex::new(r#"Meldung_ID="(?(.*?))""#).unwrap(); + + if re.is_match(&self.raw_value) { + let caps = re.captures(&self.raw_value).unwrap(); + return Some(caps["meldung_id"].to_string()); + } + + None + } + + pub fn database_id(&self) -> Option { + return match self.id() { + Some(id) => { + let re1 = Regex::new(r"^(?[0-9A-F]+)").unwrap(); + let re2 = Regex::new(r"(?[0-9]+)$").unwrap(); + + if re1.is_match(&id) { + match re1.find(&id).map(|m| m.as_str().to_string()) { + Some(val) => match u64::from_str_radix(&val, 16) { + Ok(val) => Some(val.to_string()), + _ => None, + }, + _ => None, + } + } else if re2.is_match(&id) { + re2.find(&id).map(|m| m.as_str().to_string()) + } else { + None + } + } + _ => None, + }; + } +} + +#[cfg(test)] +mod tests { + use crate::lkrexport::LkrExportProtocolFile; + + #[test] + fn should_read_xml_file_content() { + let actual = LkrExportProtocolFile::parse(include_str!("../testdaten/testdaten_1.xml")); + + assert!(actual.is_ok()); + assert_eq!(actual.unwrap().patients.len(), 2); + } + + #[test] + fn should_get_meldungen() { + let actual = LkrExportProtocolFile::parse(include_str!("../testdaten/testdaten_1.xml")); + + assert!(actual.is_ok()); + + let patients = actual.unwrap().patients; + + assert_eq!(patients[0].meldungen().len(), 1); + assert_eq!(patients[1].meldungen().len(), 1); + } + + #[test] + fn should_get_meldung_database_id() { + let actual = LkrExportProtocolFile::parse(include_str!("../testdaten/testdaten_1.xml")); + + assert!(actual.is_ok()); + + let patients = actual.unwrap().patients; + + assert_eq!( + patients[0].meldungen()[0].database_id(), + Some("1727528".to_string()) + ); + assert_eq!( + patients[1].meldungen()[0].database_id(), + Some("1727824".to_string()) + ); + } +} diff --git a/src/main.rs b/src/main.rs index 50d368f..43c6e8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,10 +28,12 @@ use itertools::Itertools; use crate::cli::{Cli, SubCommand}; use crate::common::{Check, DiffRecord, Icd10GroupSize}; use crate::database::DatabaseSource; +use crate::lkrexport::LkrExportProtocolFile; mod cli; mod common; mod database; +mod lkrexport; mod opal; mod resources; diff --git a/testdaten/testdaten_1.xml b/testdaten/testdaten_1.xml new file mode 100644 index 0000000..43976bf --- /dev/null +++ b/testdaten/testdaten_1.xml @@ -0,0 +1,89 @@ + + + + TEST + Musterstraße 1, 012345 Musterhausen + + + + + E123456789 + 123456789 + Tester + + Patrick + Tester + M + 01.01.1980 + + + Testweg + 1 + DE + 01234 + Musterhausen + + + + + + 11.06.2024 + I + statusaenderung + + C17.2 + 10 2015 GM + 10.06.2024 + T + + + + 11.06.2024 + praeth + + + + + + + + E123456789 + 123456789 + Tester + + Patricia + Tester + W + 01.01.1980 + + + Testweg + 1 + DE + 01234 + Musterhausen + + + + + + 11.06.2024 + I + statusaenderung + + C17.2 + 10 2015 GM + 01.01.2024 + T + + + + 10.01.2024 + praeth + + + + + + +