diff --git a/src/parser.rs b/src/parser.rs index 81b01f2..f7b9df6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -156,7 +156,10 @@ impl Parser { // we'll trim them out uid.value = uid.value.replace("\u{200b}", ""); } - 1 => uid.name = text.unwrap(), + 1 => { + uid.full_name = text.unwrap(); + uid.normalized_name = Self::normalize_uid_name(&uid.full_name); + } 2 => match text.unwrap().as_ref() { "Application Context Name" => uid.kind = Kind::ApplicationContextName, "Application Hosting Model" => uid.kind = Kind::ApplicationHostingModel, @@ -297,4 +300,48 @@ impl Parser { reader.read_to_string(&mut content)?; Ok(content) } + + fn normalize_uid_name(full_uid_name: &str) -> String { + let mut normalized_uid_name = full_uid_name.to_owned(); + if normalized_uid_name.contains(":") { + let colon_index = normalized_uid_name.find(":").unwrap(); + normalized_uid_name.split_off(colon_index); + normalized_uid_name.shrink_to_fit(); + } + + if normalized_uid_name.contains(" (Retired)") { + normalized_uid_name = normalized_uid_name.replace(" (Retired)", ""); + } + + normalized_uid_name + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn normalize_uid_name_doesnt_change_input_without_colon_or_retired() { + assert_eq!( + Parser::normalize_uid_name("Test String"), + "Test String".to_owned() + ); + } + + #[test] + fn normalize_uid_name_strips_everything_starting_at_colon() { + assert_eq!( + Parser::normalize_uid_name("Test String: With a colon"), + "Test String".to_owned() + ); + } + + #[test] + fn normalize_uid_name_removes_retired() { + assert_eq!( + Parser::normalize_uid_name("Test String (Retired)"), + "Test String".to_owned() + ); + } } diff --git a/src/uid.rs b/src/uid.rs index c05481f..8202192 100644 --- a/src/uid.rs +++ b/src/uid.rs @@ -19,8 +19,28 @@ pub enum Kind { #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct UID { + /// The value of the UID (e.g. "1.2.840.10008.1.1" for "Verification SOP + /// Class") pub value: String, - pub name: String, + + /// The full name of the UID as given in the DICOM Standard (e.g. "Implicit + /// VR Little Endian: Default Transfer Syntax for DICOM") + pub full_name: String, + + /// A normalized form of the full name. The following content is trimmed + /// from the full name: + /// * everything behind a colon (e.g. full name "Implicit VR Little Endian: + /// Default Transfer Syntax for DICOM" is trimmed down to "Implicit VR + /// Little Endian") + /// * the string " (Retired)" (e.g. "Explicit VR Big Endian (Retired)" is + /// trimmed down to "Explicit VR Big Endian") + /// + /// Note that there can still be some "noise" in this due to the format of + /// the original names. Examples: "JPEG Lossless, Non-Hierarchical (Process + /// 14)" or "MPEG-4 AVC/H.264 High Profile / Level 4.2 For 2D Video". + pub normalized_name: String, + + /// The type of this UID pub kind: Kind, } @@ -28,7 +48,8 @@ impl UID { pub fn new() -> Self { UID { value: String::new(), - name: String::new(), + normalized_name: String::new(), + full_name: String::new(), kind: Kind::TransferSyntax, } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index d5e89d6..150b17f 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -175,11 +175,18 @@ fn parse_unique_identifier_registry_from_file() { Ok(uids) => { assert_eq!(uids.len(), 400); - let explicit_vr_little_endian = &uids[2]; - assert_eq!(explicit_vr_little_endian.value, "1.2.840.10008.1.2.1"); - assert_eq!(explicit_vr_little_endian.name, "Explicit VR Little Endian"); + let implicit_little_endian = &uids[1]; + assert_eq!(implicit_little_endian.value, "1.2.840.10008.1.2"); assert_eq!( - explicit_vr_little_endian.kind, + implicit_little_endian.full_name, + "Implicit VR Little Endian: Default Transfer Syntax for DICOM" + ); + assert_eq!( + implicit_little_endian.normalized_name, + "Implicit VR Little Endian" + ); + assert_eq!( + implicit_little_endian.kind, dict_parser::Kind::TransferSyntax ); } @@ -200,7 +207,11 @@ fn parse_unique_identifier_registry_from_downloaded_dict() { // checking some random element let verification_sop_class = &uids[0]; assert_eq!(verification_sop_class.value, "1.2.840.10008.1.1"); - assert_eq!(verification_sop_class.name, "Verification SOP Class"); + assert_eq!(verification_sop_class.full_name, "Verification SOP Class"); + assert_eq!( + verification_sop_class.normalized_name, + "Verification SOP Class" + ); assert_eq!(verification_sop_class.kind, dict_parser::Kind::SopClass); } Err(e) => assert!(false, e.to_string()),