3
3
//! element header, and element composite types.
4
4
5
5
use crate :: error:: { Error , Result } ;
6
- use crate :: value:: { DicomValueType , PrimitiveValue , Value } ;
6
+ use crate :: value:: { PrimitiveValue , Value } ;
7
7
use std:: borrow:: Cow ;
8
8
use std:: cmp:: Ordering ;
9
9
use std:: fmt;
10
10
use std:: str:: { from_utf8, FromStr } ;
11
11
12
+ /// Trait for any DICOM entity (element or item) which may have a length.
13
+ pub trait HasLength {
14
+ /// Retrieve the value data's length as specified by the data element or
15
+ /// item, in bytes.
16
+ ///
17
+ /// It is named `length` to make it distinct from the conventional method
18
+ /// signature `len(&self) -> usize` for the number of elements of a
19
+ /// collection.
20
+ ///
21
+ /// According to the standard, the concrete value size may be undefined,
22
+ /// which can be the case for sequence elements or specific primitive
23
+ /// values.
24
+ fn length ( & self ) -> Length ;
25
+ }
26
+
12
27
/// A trait for a data type containing a DICOM header.
13
28
#[ allow( clippy:: len_without_is_empty) ]
14
- pub trait Header {
29
+ pub trait Header : HasLength {
15
30
/// Retrieve the element's tag as a `(group, element)` tuple.
16
31
fn tag ( & self ) -> Tag ;
17
32
18
- /// Retrieve the value data's length as specified by the data element, in bytes.
19
- /// According to the standard, the concrete value size may be undefined,
20
- /// which can be the case for sequence elements or specific primitive values.
21
- fn len ( & self ) -> Length ;
22
-
23
33
/// Check whether this is the header of an item.
24
34
fn is_item ( & self ) -> bool {
25
35
self . tag ( ) == Tag ( 0xFFFE , 0xE000 )
@@ -36,9 +46,23 @@ pub trait Header {
36
46
}
37
47
}
38
48
49
+ /// Stub type representing a non-existing DICOM object.
50
+ ///
51
+ /// This type implements `HasLength`, but cannot be instantiated.
52
+ /// This makes it so that `Value<EmptyObject>` is sure to be either a primitive
53
+ /// value or a sequence with no items.
54
+ #[ derive( Debug , PartialEq ) ]
55
+ pub enum EmptyObject { }
56
+
57
+ impl HasLength for EmptyObject {
58
+ fn length ( & self ) -> Length {
59
+ unreachable ! ( )
60
+ }
61
+ }
62
+
39
63
/// A data type that represents and owns a DICOM data element. Unlike
40
64
/// [`PrimitiveDataElement`], this type may contain multiple data elements
41
- /// through the item sequence VR (of type `I`).
65
+ /// through the item sequence VR (where each item contains an object of type `I`).
42
66
#[ derive( Debug , PartialEq , Clone ) ]
43
67
pub struct DataElement < I > {
44
68
header : DataElementHeader ,
@@ -91,15 +115,24 @@ impl<'a> PrimitiveDataElementRef<'a> {
91
115
PrimitiveDataElementRef { header, value }
92
116
}
93
117
}
118
+ impl < I > HasLength for DataElement < I > {
119
+ #[ inline]
120
+ fn length ( & self ) -> Length {
121
+ self . header . length ( )
122
+ }
123
+ }
124
+
94
125
impl < I > Header for DataElement < I > {
95
126
#[ inline]
96
127
fn tag ( & self ) -> Tag {
97
128
self . header . tag ( )
98
129
}
130
+ }
99
131
132
+ impl < I > HasLength for & DataElement < I > {
100
133
#[ inline]
101
- fn len ( & self ) -> Length {
102
- self . header . len ( )
134
+ fn length ( & self ) -> Length {
135
+ ( * * self ) . length ( )
103
136
}
104
137
}
105
138
@@ -109,9 +142,12 @@ impl<'a, I> Header for &'a DataElement<I> {
109
142
( * * self ) . tag ( )
110
143
}
111
144
145
+ }
146
+
147
+ impl < ' v , I > HasLength for DataElementRef < ' v , I > {
112
148
#[ inline]
113
- fn len ( & self ) -> Length {
114
- ( * * self ) . len ( )
149
+ fn length ( & self ) -> Length {
150
+ self . header . length ( )
115
151
}
116
152
}
117
153
@@ -120,17 +156,9 @@ impl<'v, I> Header for DataElementRef<'v, I> {
120
156
fn tag ( & self ) -> Tag {
121
157
self . header . tag ( )
122
158
}
123
-
124
- #[ inline]
125
- fn len ( & self ) -> Length {
126
- self . header . len ( )
127
- }
128
159
}
129
160
130
- impl < I > DataElement < I >
131
- where
132
- I : DicomValueType ,
133
- {
161
+ impl < I > DataElement < I > {
134
162
/// Create an empty data element.
135
163
pub fn empty ( tag : Tag , vr : VR ) -> Self {
136
164
DataElement {
@@ -143,24 +171,17 @@ where
143
171
}
144
172
}
145
173
146
- /// Create a primitive data element from the given parts. This method will not check
147
- /// whether the value representation is compatible with the given value.
148
- pub fn new ( tag : Tag , vr : VR , value : Value < I > ) -> Self {
149
- DataElement {
150
- header : DataElementHeader {
151
- tag,
152
- vr,
153
- len : value. size ( ) ,
154
- } ,
155
- value,
156
- }
157
- }
158
-
159
174
/// Retrieve the element header.
160
175
pub fn header ( & self ) -> & DataElementHeader {
161
176
& self . header
162
177
}
163
178
179
+ /// Retrieve the value representation, which may be unknown or not
180
+ /// applicable.
181
+ pub fn vr ( & self ) -> VR {
182
+ self . header . vr ( )
183
+ }
184
+
164
185
/// Retrieve the data value.
165
186
pub fn value ( & self ) -> & Value < I > {
166
187
& self . value
@@ -172,11 +193,25 @@ where
172
193
pub fn into_value ( self ) -> Value < I > {
173
194
self . value
174
195
}
196
+ }
175
197
176
- /// Retrieve the value representation, which may be unknown or not
177
- /// applicable.
178
- pub fn vr ( & self ) -> VR {
179
- self . header . vr ( )
198
+ impl < I > DataElement < I >
199
+ where
200
+ I : HasLength ,
201
+ {
202
+ /// Create a primitive data element from the given parts.
203
+ ///
204
+ /// This method will not check whether the value representation is
205
+ /// compatible with the given value.
206
+ pub fn new ( tag : Tag , vr : VR , value : Value < I > ) -> Self {
207
+ DataElement {
208
+ header : DataElementHeader {
209
+ tag,
210
+ vr,
211
+ len : value. length ( ) ,
212
+ } ,
213
+ value,
214
+ }
180
215
}
181
216
182
217
/// Retrieve the element's value as a single string.
@@ -187,7 +222,7 @@ where
187
222
188
223
impl < ' v , I > DataElementRef < ' v , I >
189
224
where
190
- I : DicomValueType ,
225
+ I : HasLength ,
191
226
{
192
227
/// Create a data element from the given parts. This method will not check
193
228
/// whether the value representation is compatible with the value. Caution
@@ -197,7 +232,7 @@ where
197
232
header : DataElementHeader {
198
233
tag,
199
234
vr,
200
- len : value. size ( ) ,
235
+ len : value. length ( ) ,
201
236
} ,
202
237
value,
203
238
}
@@ -226,19 +261,24 @@ pub struct DataElementHeader {
226
261
pub len : Length ,
227
262
}
228
263
264
+ impl HasLength for DataElementHeader {
265
+ #[ inline]
266
+ fn length ( & self ) -> Length {
267
+ self . len
268
+ }
269
+ }
270
+
229
271
impl Header for DataElementHeader {
272
+ #[ inline]
230
273
fn tag ( & self ) -> Tag {
231
274
self . tag
232
275
}
233
-
234
- fn len ( & self ) -> Length {
235
- self . len
236
- }
237
276
}
238
277
239
278
impl DataElementHeader {
240
279
/// Create a new data element header with the given properties.
241
280
/// This is just a trivial constructor.
281
+ #[ inline]
242
282
pub fn new < T : Into < Tag > > ( tag : T , vr : VR , len : Length ) -> DataElementHeader {
243
283
DataElementHeader {
244
284
tag : tag. into ( ) ,
@@ -248,6 +288,7 @@ impl DataElementHeader {
248
288
}
249
289
250
290
/// Retrieve the element's value representation, which can be unknown.
291
+ #[ inline]
251
292
pub fn vr ( & self ) -> VR {
252
293
self . vr
253
294
}
@@ -258,7 +299,7 @@ impl From<SequenceItemHeader> for DataElementHeader {
258
299
DataElementHeader {
259
300
tag : value. tag ( ) ,
260
301
vr : VR :: UN ,
261
- len : value. len ( ) ,
302
+ len : value. length ( ) ,
262
303
}
263
304
}
264
305
}
@@ -309,21 +350,24 @@ impl SequenceItemHeader {
309
350
}
310
351
}
311
352
353
+ impl HasLength for SequenceItemHeader {
354
+ #[ inline]
355
+ fn length ( & self ) -> Length {
356
+ match * self {
357
+ SequenceItemHeader :: Item { len } => len,
358
+ SequenceItemHeader :: ItemDelimiter | SequenceItemHeader :: SequenceDelimiter => Length ( 0 ) ,
359
+ }
360
+ }
361
+ }
312
362
impl Header for SequenceItemHeader {
363
+ #[ inline]
313
364
fn tag ( & self ) -> Tag {
314
365
match * self {
315
366
SequenceItemHeader :: Item { .. } => Tag ( 0xFFFE , 0xE000 ) ,
316
367
SequenceItemHeader :: ItemDelimiter => Tag ( 0xFFFE , 0xE00D ) ,
317
368
SequenceItemHeader :: SequenceDelimiter => Tag ( 0xFFFE , 0xE0DD ) ,
318
369
}
319
370
}
320
-
321
- fn len ( & self ) -> Length {
322
- match * self {
323
- SequenceItemHeader :: Item { len } => len,
324
- SequenceItemHeader :: ItemDelimiter | SequenceItemHeader :: SequenceDelimiter => Length ( 0 ) ,
325
- }
326
- }
327
371
}
328
372
329
373
/// An enum type for a DICOM value representation.
0 commit comments