dicom_core/dictionary/
uid.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! Core UID dictionary types

use std::str::FromStr;

/// Type trait for a dictionary of known DICOM unique identifiers (UIDs).
///
/// UID dictionaries provide the means to
/// look up information at run-time about a certain UID.
///
/// The methods herein have no generic parameters,
/// so as to enable being used as a trait object.
pub trait UidDictionary {
    /// The type of the dictionary entry.
    type Entry: UidDictionaryEntry;

    /// Fetch an entry by its usual keyword (e.g. CTImageStorage).
    /// Aliases (or keywords)
    /// are usually in UpperCamelCase,
    /// not separated by spaces,
    /// and are case sensitive.
    fn by_keyword(&self, keyword: &str) -> Option<&Self::Entry>;

    /// Fetch an entry by its UID.
    fn by_uid(&self, uid: &str) -> Option<&Self::Entry>;
}

/// UID dictionary entry type
pub trait UidDictionaryEntry {
    /// Get the UID proper.
    fn uid(&self) -> &str;

    /// Get the full name of the identifier.
    fn name(&self) -> &str;

    /// The alias of the UID, with no spaces, usually in UpperCamelCase.
    fn alias(&self) -> &str;

    /// Get whether the UID is retired.
    fn is_retired(&self) -> bool;
}

/// A data type for a dictionary entry using string slices
/// for its data.
#[derive(Debug, PartialEq, Clone)]
pub struct UidDictionaryEntryRef<'a> {
    /// The UID proper
    pub uid: &'a str,
    /// The full name of the identifier,
    /// which may contain spaces
    pub name: &'a str,
    /// The alias of the identifier,
    /// with no spaces, usually in UpperCamelCase
    pub alias: &'a str,
    /// The type of UID
    pub r#type: UidType,
    /// Whether this SOP class is retired
    pub retired: bool,
}

impl<'a> UidDictionaryEntryRef<'a> {
    pub const fn new(
        uid: &'a str,
        name: &'a str,
        alias: &'a str,
        r#type: UidType,
        retired: bool,
    ) -> Self {
        UidDictionaryEntryRef {
            uid,
            name,
            alias,
            r#type,
            retired,
        }
    }
}

impl UidDictionaryEntry for UidDictionaryEntryRef<'_> {
    fn uid(&self) -> &str {
        self.uid
    }

    fn name(&self) -> &str {
        self.name
    }

    fn alias(&self) -> &str {
        self.alias
    }

    fn is_retired(&self) -> bool {
        self.retired
    }
}

/// Enum for all UID types recognized by the standard.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
pub enum UidType {
    /// SOP Class
    SopClass,
    /// Meta SOP Class
    MetaSopClass,
    /// Transfer Syntax
    TransferSyntax,
    /// Well-known SOP Instance
    WellKnownSopInstance,
    /// DICOM UIDs as a Coding Scheme
    DicomUidsAsCodingScheme,
    /// Coding Scheme
    CodingScheme,
    /// Application Context Name
    ApplicationContextName,
    /// Service Class
    ServiceClass,
    /// Application Hosting Model
    ApplicationHostingModel,
    /// Mapping Resource
    MappingResource,
    /// LDAP OID
    LdapOid,
    /// Synchronization Frame of Reference
    SynchronizationFrameOfReference,
}

impl FromStr for UidType {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.trim() {
            "SOP Class" => Ok(UidType::SopClass),
            "Meta SOP Class" => Ok(UidType::MetaSopClass),
            "Transfer Syntax" => Ok(UidType::TransferSyntax),
            "Well-known SOP Instance" => Ok(UidType::WellKnownSopInstance),
            "DICOM UIDs as a Coding Scheme" => Ok(UidType::DicomUidsAsCodingScheme),
            "Coding Scheme" => Ok(UidType::CodingScheme),
            "Application Context Name" => Ok(UidType::ApplicationContextName),
            "Service Class" => Ok(UidType::ServiceClass),
            "Application Hosting Model" => Ok(UidType::ApplicationHostingModel),
            "Mapping Resource" => Ok(UidType::MappingResource),
            "LDAP OID" => Ok(UidType::LdapOid),
            "Synchronization Frame of Reference" => Ok(UidType::SynchronizationFrameOfReference),
            _ => Err(()),
        }
    }
}

impl std::fmt::Display for UidType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let str = match self {
            UidType::SopClass => "SOP Class",
            UidType::MetaSopClass => "Meta SOP Class",
            UidType::TransferSyntax => "Transfer Syntax",
            UidType::WellKnownSopInstance => "Well-known SOP Instance",
            UidType::DicomUidsAsCodingScheme => "DICOM UIDs as a Coding Scheme",
            UidType::CodingScheme => "Coding Scheme",
            UidType::ApplicationContextName => "Application Context Name",
            UidType::ServiceClass => "Service Class",
            UidType::ApplicationHostingModel => "Application Hosting Model",
            UidType::MappingResource => "Mapping Resource",
            UidType::LdapOid => "LDAP OID",
            UidType::SynchronizationFrameOfReference => "Synchronization Frame of Reference",
        };
        f.write_str(str)
    }
}