dicom_core/dictionary/
uid.rs

1//! Core UID dictionary types
2
3use std::str::FromStr;
4
5/// Type trait for a dictionary of known DICOM unique identifiers (UIDs).
6///
7/// UID dictionaries provide the means to
8/// look up information at run-time about a certain UID.
9///
10/// The methods herein have no generic parameters,
11/// so as to enable being used as a trait object.
12pub trait UidDictionary {
13    /// The type of the dictionary entry.
14    type Entry: UidDictionaryEntry;
15
16    /// Fetch an entry by its usual keyword (e.g. CTImageStorage).
17    /// Aliases (or keywords)
18    /// are usually in UpperCamelCase,
19    /// not separated by spaces,
20    /// and are case sensitive.
21    fn by_keyword(&self, keyword: &str) -> Option<&Self::Entry>;
22
23    /// Fetch an entry by its UID.
24    fn by_uid(&self, uid: &str) -> Option<&Self::Entry>;
25}
26
27/// UID dictionary entry type
28pub trait UidDictionaryEntry {
29    /// Get the UID proper.
30    fn uid(&self) -> &str;
31
32    /// Get the full name of the identifier.
33    fn name(&self) -> &str;
34
35    /// The alias of the UID, with no spaces, usually in UpperCamelCase.
36    fn alias(&self) -> &str;
37
38    /// Get whether the UID is retired.
39    fn is_retired(&self) -> bool;
40}
41
42/// A data type for a dictionary entry using string slices
43/// for its data.
44#[derive(Debug, PartialEq, Clone)]
45pub struct UidDictionaryEntryRef<'a> {
46    /// The UID proper
47    pub uid: &'a str,
48    /// The full name of the identifier,
49    /// which may contain spaces
50    pub name: &'a str,
51    /// The alias of the identifier,
52    /// with no spaces, usually in UpperCamelCase
53    pub alias: &'a str,
54    /// The type of UID
55    pub r#type: UidType,
56    /// Whether this SOP class is retired
57    pub retired: bool,
58}
59
60impl<'a> UidDictionaryEntryRef<'a> {
61    pub const fn new(
62        uid: &'a str,
63        name: &'a str,
64        alias: &'a str,
65        r#type: UidType,
66        retired: bool,
67    ) -> Self {
68        UidDictionaryEntryRef {
69            uid,
70            name,
71            alias,
72            r#type,
73            retired,
74        }
75    }
76}
77
78impl<'a> UidDictionaryEntry for UidDictionaryEntryRef<'a> {
79    fn uid(&self) -> &str {
80        self.uid
81    }
82
83    fn name(&self) -> &str {
84        self.name
85    }
86
87    fn alias(&self) -> &str {
88        self.alias
89    }
90
91    fn is_retired(&self) -> bool {
92        self.retired
93    }
94}
95
96/// Enum for all UID types recognized by the standard.
97#[non_exhaustive]
98#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
99pub enum UidType {
100    /// SOP Class
101    SopClass,
102    /// Meta SOP Class
103    MetaSopClass,
104    /// Transfer Syntax
105    TransferSyntax,
106    /// Well-known SOP Instance
107    WellKnownSopInstance,
108    /// DICOM UIDs as a Coding Scheme
109    DicomUidsAsCodingScheme,
110    /// Coding Scheme
111    CodingScheme,
112    /// Application Context Name
113    ApplicationContextName,
114    /// Service Class
115    ServiceClass,
116    /// Application Hosting Model
117    ApplicationHostingModel,
118    /// Mapping Resource
119    MappingResource,
120    /// LDAP OID
121    LdapOid,
122    /// Synchronization Frame of Reference
123    SynchronizationFrameOfReference,
124}
125
126impl FromStr for UidType {
127    type Err = ();
128
129    fn from_str(s: &str) -> Result<Self, Self::Err> {
130        match s.trim() {
131            "SOP Class" => Ok(UidType::SopClass),
132            "Meta SOP Class" => Ok(UidType::MetaSopClass),
133            "Transfer Syntax" => Ok(UidType::TransferSyntax),
134            "Well-known SOP Instance" => Ok(UidType::WellKnownSopInstance),
135            "DICOM UIDs as a Coding Scheme" => Ok(UidType::DicomUidsAsCodingScheme),
136            "Coding Scheme" => Ok(UidType::CodingScheme),
137            "Application Context Name" => Ok(UidType::ApplicationContextName),
138            "Service Class" => Ok(UidType::ServiceClass),
139            "Application Hosting Model" => Ok(UidType::ApplicationHostingModel),
140            "Mapping Resource" => Ok(UidType::MappingResource),
141            "LDAP OID" => Ok(UidType::LdapOid),
142            "Synchronization Frame of Reference" => Ok(UidType::SynchronizationFrameOfReference),
143            _ => Err(()),
144        }
145    }
146}
147
148impl std::fmt::Display for UidType {
149    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150        let str = match self {
151            UidType::SopClass => "SOP Class",
152            UidType::MetaSopClass => "Meta SOP Class",
153            UidType::TransferSyntax => "Transfer Syntax",
154            UidType::WellKnownSopInstance => "Well-known SOP Instance",
155            UidType::DicomUidsAsCodingScheme => "DICOM UIDs as a Coding Scheme",
156            UidType::CodingScheme => "Coding Scheme",
157            UidType::ApplicationContextName => "Application Context Name",
158            UidType::ServiceClass => "Service Class",
159            UidType::ApplicationHostingModel => "Application Hosting Modle",
160            UidType::MappingResource => "Mapping Resource",
161            UidType::LdapOid => "LDAP OID",
162            UidType::SynchronizationFrameOfReference => "Synchronization Frame of Reference",
163        };
164        f.write_str(str)
165    }
166}