dicom_core/value/
mod.rs

1//! This module includes a high level abstraction over a DICOM data element's value.
2
3use crate::header::{EmptyObject, HasLength, Length, Tag};
4use num_traits::NumCast;
5use smallvec::SmallVec;
6use std::{borrow::Cow, str::FromStr};
7
8pub mod deserialize;
9pub mod fragments;
10pub mod partial;
11pub mod person_name;
12mod primitive;
13pub mod range;
14pub mod serialize;
15
16pub use self::deserialize::Error as DeserializeError;
17pub use self::partial::{DicomDate, DicomDateTime, DicomTime, PreciseDateTime};
18pub use self::person_name::PersonName;
19pub use self::range::{AsRange, DateRange, DateTimeRange, TimeRange};
20
21pub use self::primitive::{
22    CastValueError, ConvertValueError, InvalidValueReadError, ModifyValueError, PrimitiveValue,
23    ValueType,
24};
25
26/// An aggregation of one or more elements in a value.
27pub type C<T> = SmallVec<[T; 2]>;
28
29/// Type alias for the in-memory pixel data fragment data.
30pub type InMemFragment = Vec<u8>;
31
32/// A trait for a value that maps to a DICOM element data value.
33pub trait DicomValueType: HasLength {
34    /// Retrieve the specific type of this value.
35    fn value_type(&self) -> ValueType;
36
37    /// Retrieve the number of elements contained in the DICOM value.
38    ///
39    /// In a sequence value, this is the number of items in the sequence.
40    /// In an encapsulated pixel data sequence, the output is always 1.
41    /// Otherwise, the output is the number of elements effectively encoded
42    /// in the value.
43    fn cardinality(&self) -> usize;
44}
45
46/// Representation of a full DICOM value, which may be either primitive or
47/// another DICOM object.
48///
49/// `I` is the complex type for nest data set items, which should usually
50/// implement [`HasLength`].
51/// `P` is the encapsulated pixel data provider,
52/// which should usually implement `AsRef<[u8]>`.
53#[derive(Debug, Clone, PartialEq)]
54pub enum Value<I = EmptyObject, P = InMemFragment> {
55    /// Primitive value.
56    Primitive(PrimitiveValue),
57    /// A complex sequence of items.
58    Sequence(DataSetSequence<I>),
59    /// A sequence of encapsulated pixel data fragments.
60    PixelSequence(PixelFragmentSequence<P>),
61}
62
63impl<P> Value<EmptyObject, P> {
64    /// Construct an isolated DICOM pixel sequence sequence value
65    /// from a basic offset table and a list of fragments.
66    ///
67    /// This function will define the data set sequence item type `I`
68    /// to an empty object ([`EmptyObject`]),
69    /// so that it can be used more easily in isolation.
70    /// As a consequence, it cannot be directly combined with
71    /// DICOM objects that may contain sequence values.
72    /// To let the type parameter `I` be inferred from its context,
73    /// create a [`PixelFragmentSequence`] and use `Value::from` instead.
74    ///
75    /// **Note:** This function does not validate the offset table
76    /// against the fragments.
77    pub fn new_pixel_sequence<T>(offset_table: C<u32>, fragments: T) -> Self
78    where
79        T: Into<C<P>>,
80    {
81        Value::from(PixelFragmentSequence::new(offset_table, fragments))
82    }
83}
84
85impl<I> Value<I> {
86    /// Construct an isolated DICOM data set sequence value
87    /// from a list of items and length.
88    ///
89    /// This function will define the pixel data fragment type parameter `P`
90    /// to the `Value` type's default ([`InMemFragment`]),
91    /// so that it can be used more easily.
92    /// If necessary,
93    /// it is possible to let this type parameter be inferred from its context
94    /// by creating a [`DataSetSequence`] and using `Value::from` instead.
95    #[inline]
96    pub fn new_sequence<T>(items: T, length: Length) -> Self
97    where
98        T: Into<C<I>>,
99    {
100        Self::from(DataSetSequence::new(items, length))
101    }
102}
103
104impl Value {
105    /// Construct a DICOM value from a primitive value.
106    ///
107    /// This is equivalent to `Value::from` in behavior,
108    /// except that suitable type parameters are specified
109    /// instead of inferred.
110    ///
111    /// This function will automatically define
112    /// the sequence item parameter `I`
113    /// to [`EmptyObject`]
114    /// and the pixel data fragment type parameter `P`
115    /// to the default fragment data type ([`InMemFragment`]),
116    /// so that it can be used more easily in isolation.
117    /// As a consequence, it cannot be directly combined with
118    /// DICOM objects that may contain
119    /// nested data sets or encapsulated pixel data.
120    /// To let the type parameters `I` and `P` be inferred from their context,
121    /// create a value of one of the types and use `Value::from` instead.
122    ///
123    /// - [`PrimitiveValue`]
124    /// - [`PixelFragmentSequence`]
125    /// - [`DataSetSequence`]
126    #[inline]
127    pub fn new(value: PrimitiveValue) -> Self {
128        Self::from(value)
129    }
130}
131
132impl<I, P> Value<I, P> {
133    /// Obtain the number of individual values.
134    /// In a primitive, this is the number of individual elements in the value.
135    /// In a sequence item, this is the number of items.
136    /// In a pixel sequence, this is currently set to 1
137    /// regardless of the number of compressed fragments or frames.
138    pub fn multiplicity(&self) -> u32 {
139        match self {
140            Value::Primitive(v) => v.multiplicity(),
141            Value::Sequence(v) => v.multiplicity(),
142            Value::PixelSequence(..) => 1,
143        }
144    }
145
146    /// Gets a reference to the primitive value.
147    pub fn primitive(&self) -> Option<&PrimitiveValue> {
148        match self {
149            Value::Primitive(v) => Some(v),
150            _ => None,
151        }
152    }
153
154    /// Gets a mutable reference to the primitive value.
155    pub fn primitive_mut(&mut self) -> Option<&mut PrimitiveValue> {
156        match self {
157            Value::Primitive(v) => Some(v),
158            _ => None,
159        }
160    }
161
162    /// Gets a reference to the items of a sequence.
163    ///
164    /// Returns `None` if the value is not a data set sequence.
165    pub fn items(&self) -> Option<&[I]> {
166        match self {
167            Value::Sequence(v) => Some(v.items()),
168            _ => None,
169        }
170    }
171
172    /// Gets a mutable reference to the items of a sequence.
173    ///
174    /// Returns `None` if the value is not a data set sequence.
175    pub fn items_mut(&mut self) -> Option<&mut C<I>> {
176        match self {
177            Value::Sequence(v) => Some(v.items_mut()),
178            _ => None,
179        }
180    }
181
182    /// Gets a reference to the fragments of a pixel data sequence.
183    ///
184    /// Returns `None` if the value is not a pixel data sequence.
185    pub fn fragments(&self) -> Option<&[P]> {
186        match self {
187            Value::PixelSequence(v) => Some(v.fragments()),
188            _ => None,
189        }
190    }
191
192    /// Gets a mutable reference to the fragments of a pixel data sequence.
193    ///
194    /// Returns `None` if the value is not a pixel data sequence.
195    pub fn fragments_mut(&mut self) -> Option<&mut C<P>> {
196        match self {
197            Value::PixelSequence(v) => Some(v.fragments_mut()),
198            _ => None,
199        }
200    }
201
202    /// Retrieves the primitive value.
203    pub fn into_primitive(self) -> Option<PrimitiveValue> {
204        match self {
205            Value::Primitive(v) => Some(v),
206            _ => None,
207        }
208    }
209
210    /// Retrieves the data set items,
211    /// discarding the recorded length information.
212    ///
213    /// Returns `None` if the value is not a data set sequence.
214    pub fn into_items(self) -> Option<C<I>> {
215        match self {
216            Value::Sequence(v) => Some(v.into_items()),
217            _ => None,
218        }
219    }
220
221    /// Retrieves the pixel data fragments,
222    /// discarding the rest of the information.
223    pub fn into_fragments(self) -> Option<C<P>> {
224        match self {
225            Value::PixelSequence(v) => Some(v.into_fragments()),
226            _ => None,
227        }
228    }
229
230    /// Gets a reference to the encapsulated pixel data's offset table.
231    ///
232    /// Returns `None` if the value is not a pixel data sequence.
233    pub fn offset_table(&self) -> Option<&[u32]> {
234        match self {
235            Value::PixelSequence(v) => Some(v.offset_table()),
236            _ => None,
237        }
238    }
239
240    /// Gets a mutable reference to the encapsulated pixel data's offset table.
241    ///
242    /// Returns `None` if the value is not a pixel data sequence.
243    pub fn offset_table_mut(&mut self) -> Option<&mut C<u32>> {
244        match self {
245            Value::PixelSequence(v) => Some(v.offset_table_mut()),
246            _ => None,
247        }
248    }
249
250    /// Shorten this value by removing trailing elements
251    /// to fit the given limit.
252    ///
253    /// On primitive values,
254    /// elements are counted by the number of individual value items
255    /// (note that bytes in a [`PrimitiveValue::U8`]
256    /// are treated as individual items).
257    /// On data set sequences and pixel data fragment sequences,
258    /// this operation is applied to
259    /// the data set items (or fragments) in the sequence.
260    ///
261    /// Nothing is done if the value's cardinality
262    /// is already lower than or equal to the limit.
263    pub fn truncate(&mut self, limit: usize) {
264        match self {
265            Value::Primitive(v) => v.truncate(limit),
266            Value::Sequence(v) => v.truncate(limit),
267            Value::PixelSequence(v) => v.truncate(limit),
268        }
269    }
270}
271
272impl<I, P> From<&str> for Value<I, P> {
273    /// Converts a string into a primitive textual value.
274    fn from(value: &str) -> Self {
275        Value::Primitive(PrimitiveValue::from(value))
276    }
277}
278
279impl<I, P> From<String> for Value<I, P> {
280    /// Converts a string into a primitive textual value.
281    fn from(value: String) -> Self {
282        Value::Primitive(PrimitiveValue::from(value))
283    }
284}
285
286impl<I, P> From<DicomDate> for Value<I, P> {
287    /// Converts the DICOM date into a primitive value.
288    fn from(value: DicomDate) -> Self {
289        Value::Primitive(PrimitiveValue::from(value))
290    }
291}
292
293impl<I, P> From<DicomTime> for Value<I, P> {
294    /// Converts the DICOM time into a primitive value.
295    fn from(value: DicomTime) -> Self {
296        Value::Primitive(PrimitiveValue::from(value))
297    }
298}
299
300impl<I, P> From<DicomDateTime> for Value<I, P> {
301    /// Converts the DICOM date-time into a primitive value.
302    fn from(value: DicomDateTime) -> Self {
303        Value::Primitive(PrimitiveValue::from(value))
304    }
305}
306
307impl<I, P> HasLength for Value<I, P> {
308    fn length(&self) -> Length {
309        match self {
310            Value::Primitive(v) => v.length(),
311            Value::Sequence(v) => v.length(),
312            Value::PixelSequence(v) => v.length(),
313        }
314    }
315}
316
317impl<I, P> DicomValueType for Value<I, P> {
318    fn value_type(&self) -> ValueType {
319        match self {
320            Value::Primitive(v) => v.value_type(),
321            Value::Sequence(..) => ValueType::DataSetSequence,
322            Value::PixelSequence(..) => ValueType::PixelSequence,
323        }
324    }
325
326    fn cardinality(&self) -> usize {
327        match self {
328            Value::Primitive(v) => v.cardinality(),
329            Value::Sequence(DataSetSequence { items, .. }) => items.len(),
330            Value::PixelSequence { .. } => 1,
331        }
332    }
333}
334
335impl<I, P> Value<I, P>
336where
337    I: HasLength,
338{
339    /// Convert the full primitive value into a clean string.
340    ///
341    /// The value is converted into a strings
342    /// as described in [`PrimitiveValue::to_str`].
343    /// If the value contains multiple strings,
344    /// they are trimmed at the end and concatenated
345    /// (separated by the standard DICOM value delimiter `'\\'`)
346    /// into an owned string.
347    ///
348    /// Returns an error if the value is not primitive.
349    pub fn to_str(&self) -> Result<Cow<str>, ConvertValueError> {
350        match self {
351            Value::Primitive(prim) => Ok(prim.to_str()),
352            _ => Err(ConvertValueError {
353                requested: "string",
354                original: self.value_type(),
355                cause: None,
356            }),
357        }
358    }
359
360    /// Convert the full primitive value into a single raw string,
361    /// with trailing whitespace kept.
362    ///
363    /// If the value contains multiple strings, they are concatenated
364    /// (separated by the standard DICOM value delimiter `'\\'`)
365    /// into an owned string.
366    ///
367    /// Returns an error if the value is not primitive.
368    pub fn to_raw_str(&self) -> Result<Cow<str>, ConvertValueError> {
369        match self {
370            Value::Primitive(prim) => Ok(prim.to_raw_str()),
371            _ => Err(ConvertValueError {
372                requested: "string",
373                original: self.value_type(),
374                cause: None,
375            }),
376        }
377    }
378
379    /// Convert the full primitive value into a sequence of strings.
380    ///
381    /// If the value is a primitive, it will be converted into
382    /// a vector of strings as described in [`PrimitiveValue::to_multi_str`].
383    ///
384    /// Returns an error if the value is not primitive.
385    ///
386    /// [`PrimitiveValue::to_multi_str`]: ../enum.PrimitiveValue.html#to_multi_str
387    pub fn to_multi_str(&self) -> Result<Cow<[String]>, CastValueError> {
388        match self {
389            Value::Primitive(prim) => Ok(prim.to_multi_str()),
390            _ => Err(CastValueError {
391                requested: "string",
392                got: self.value_type(),
393            }),
394        }
395    }
396
397    /// Convert the full primitive value into raw bytes.
398    ///
399    /// String values already encoded with the `Str` and `Strs` variants
400    /// are provided in UTF-8.
401    ///
402    /// Returns an error if the value is not primitive.
403    pub fn to_bytes(&self) -> Result<Cow<[u8]>, ConvertValueError> {
404        match self {
405            Value::Primitive(prim) => Ok(prim.to_bytes()),
406            _ => Err(ConvertValueError {
407                requested: "bytes",
408                original: self.value_type(),
409                cause: None,
410            }),
411        }
412    }
413
414    /// Retrieve and convert the primitive value into an integer.
415    ///
416    /// If the value is a primitive, it will be converted into
417    /// an integer as described in [`PrimitiveValue::to_int`].
418    ///
419    /// [`PrimitiveValue::to_int`]: ../enum.PrimitiveValue.html#to_int
420    pub fn to_int<T>(&self) -> Result<T, ConvertValueError>
421    where
422        T: Clone,
423        T: NumCast,
424        T: FromStr<Err = std::num::ParseIntError>,
425    {
426        match self {
427            Value::Primitive(v) => v.to_int::<T>(),
428            _ => Err(ConvertValueError {
429                requested: "integer",
430                original: self.value_type(),
431                cause: None,
432            }),
433        }
434    }
435
436    /// Retrieve and convert the primitive value into a sequence of integers.
437    ///
438    /// If the value is a primitive, it will be converted into
439    /// a vector of integers as described in [PrimitiveValue::to_multi_int].
440    ///
441    /// [PrimitiveValue::to_multi_int]: ../enum.PrimitiveValue.html#to_multi_int
442    pub fn to_multi_int<T>(&self) -> Result<Vec<T>, ConvertValueError>
443    where
444        T: Clone,
445        T: NumCast,
446        T: FromStr<Err = std::num::ParseIntError>,
447    {
448        match self {
449            Value::Primitive(v) => v.to_multi_int::<T>(),
450            _ => Err(ConvertValueError {
451                requested: "integer",
452                original: self.value_type(),
453                cause: None,
454            }),
455        }
456    }
457
458    /// Retrieve and convert the primitive value
459    /// into a single-precision floating point number.
460    ///
461    /// If the value is a primitive, it will be converted into
462    /// a number as described in [`PrimitiveValue::to_float32`].
463    ///
464    /// [`PrimitiveValue::to_float32`]: ../enum.PrimitiveValue.html#to_float32
465    pub fn to_float32(&self) -> Result<f32, ConvertValueError> {
466        match self {
467            Value::Primitive(v) => v.to_float32(),
468            _ => Err(ConvertValueError {
469                requested: "float32",
470                original: self.value_type(),
471                cause: None,
472            }),
473        }
474    }
475
476    /// Retrieve and convert the primitive value
477    /// into a sequence of single-precision floating point numbers.
478    ///
479    /// If the value is a primitive, it will be converted into
480    /// a vector of numbers as described in [`PrimitiveValue::to_multi_float32`].
481    ///
482    /// [`PrimitiveValue::to_multi_float32`]: ../enum.PrimitiveValue.html#to_multi_float32
483    pub fn to_multi_float32(&self) -> Result<Vec<f32>, ConvertValueError> {
484        match self {
485            Value::Primitive(v) => v.to_multi_float32(),
486            _ => Err(ConvertValueError {
487                requested: "float32",
488                original: self.value_type(),
489                cause: None,
490            }),
491        }
492    }
493
494    /// Retrieve and convert the primitive value
495    /// into a double-precision floating point number.
496    ///
497    /// If the value is a primitive, it will be converted into
498    /// a number as described in [`PrimitiveValue::to_float64`].
499    ///
500    /// [`PrimitiveValue::to_float64`]: ../enum.PrimitiveValue.html#to_float64
501    pub fn to_float64(&self) -> Result<f64, ConvertValueError> {
502        match self {
503            Value::Primitive(v) => v.to_float64(),
504            _ => Err(ConvertValueError {
505                requested: "float64",
506                original: self.value_type(),
507                cause: None,
508            }),
509        }
510    }
511
512    /// Retrieve and convert the primitive value
513    /// into a sequence of double-precision floating point numbers.
514    ///
515    /// If the value is a primitive, it will be converted into
516    /// a vector of numbers as described in [`PrimitiveValue::to_multi_float64`].
517    ///
518    /// [`PrimitiveValue::to_multi_float64`]: ../enum.PrimitiveValue.html#to_multi_float64
519    pub fn to_multi_float64(&self) -> Result<Vec<f64>, ConvertValueError> {
520        match self {
521            Value::Primitive(v) => v.to_multi_float64(),
522            _ => Err(ConvertValueError {
523                requested: "float64",
524                original: self.value_type(),
525                cause: None,
526            }),
527        }
528    }
529
530    /// Retrieve and convert the primitive value into a `DicomDate`.
531    ///
532    /// If the value is a primitive, it will be converted into
533    /// a `DicomDate` as described in [`PrimitiveValue::to_date`].
534    ///
535    pub fn to_date(&self) -> Result<DicomDate, ConvertValueError> {
536        match self {
537            Value::Primitive(v) => v.to_date(),
538            _ => Err(ConvertValueError {
539                requested: "DicomDate",
540                original: self.value_type(),
541                cause: None,
542            }),
543        }
544    }
545
546    /// Retrieve and convert the primitive value into a sequence of `DicomDate`s.
547    ///
548    /// If the value is a primitive, it will be converted into
549    /// a vector of `DicomDate` as described in [`PrimitiveValue::to_multi_date`].
550    ///
551    pub fn to_multi_date(&self) -> Result<Vec<DicomDate>, ConvertValueError> {
552        match self {
553            Value::Primitive(v) => v.to_multi_date(),
554            _ => Err(ConvertValueError {
555                requested: "DicomDate",
556                original: self.value_type(),
557                cause: None,
558            }),
559        }
560    }
561
562    /// Retrieve and convert the primitive value into a `DicomTime`.
563    ///
564    /// If the value is a primitive, it will be converted into
565    /// a `DicomTime` as described in [`PrimitiveValue::to_time`].
566    ///
567    pub fn to_time(&self) -> Result<DicomTime, ConvertValueError> {
568        match self {
569            Value::Primitive(v) => v.to_time(),
570            _ => Err(ConvertValueError {
571                requested: "DicomTime",
572                original: self.value_type(),
573                cause: None,
574            }),
575        }
576    }
577
578    /// Retrieve and convert the primitive value into a sequence of `DicomTime`s.
579    ///
580    /// If the value is a primitive, it will be converted into
581    /// a vector of `DicomTime` as described in [`PrimitiveValue::to_multi_time`].
582    ///
583    pub fn to_multi_time(&self) -> Result<Vec<DicomTime>, ConvertValueError> {
584        match self {
585            Value::Primitive(v) => v.to_multi_time(),
586            _ => Err(ConvertValueError {
587                requested: "DicomTime",
588                original: self.value_type(),
589                cause: None,
590            }),
591        }
592    }
593
594    /// Retrieve and convert the primitive value into a `DicomDateTime`.
595    ///
596    /// If the value is a primitive, it will be converted into
597    /// a `DateTime` as described in [`PrimitiveValue::to_datetime`].
598    ///
599    pub fn to_datetime(&self) -> Result<DicomDateTime, ConvertValueError> {
600        match self {
601            Value::Primitive(v) => v.to_datetime(),
602            _ => Err(ConvertValueError {
603                requested: "DicomDateTime",
604                original: self.value_type(),
605                cause: None,
606            }),
607        }
608    }
609
610    /// Retrieve and convert the primitive value into a sequence of `DicomDateTime`s.
611    ///
612    /// If the value is a primitive, it will be converted into
613    /// a vector of `DicomDateTime` as described in [`PrimitiveValue::to_multi_datetime`].
614    ///
615    pub fn to_multi_datetime(&self) -> Result<Vec<DicomDateTime>, ConvertValueError> {
616        match self {
617            Value::Primitive(v) => v.to_multi_datetime(),
618            _ => Err(ConvertValueError {
619                requested: "DicomDateTime",
620                original: self.value_type(),
621                cause: None,
622            }),
623        }
624    }
625
626    /// Retrieve and convert the primitive value into a `DateRange`.
627    ///
628    /// If the value is a primitive, it will be converted into
629    /// a `DateRange` as described in [`PrimitiveValue::to_date_range`].
630    ///
631    pub fn to_date_range(&self) -> Result<DateRange, ConvertValueError> {
632        match self {
633            Value::Primitive(v) => v.to_date_range(),
634            _ => Err(ConvertValueError {
635                requested: "DateRange",
636                original: self.value_type(),
637                cause: None,
638            }),
639        }
640    }
641
642    /// Retrieve and convert the primitive value into a `TimeRange`.
643    ///
644    /// If the value is a primitive, it will be converted into
645    /// a `TimeRange` as described in [`PrimitiveValue::to_time_range`].
646    ///
647    pub fn to_time_range(&self) -> Result<TimeRange, ConvertValueError> {
648        match self {
649            Value::Primitive(v) => v.to_time_range(),
650            _ => Err(ConvertValueError {
651                requested: "TimeRange",
652                original: self.value_type(),
653                cause: None,
654            }),
655        }
656    }
657
658    /// Retrieve and convert the primitive value into a `DateTimeRange`.
659    ///
660    /// If the value is a primitive, it will be converted into
661    /// a `DateTimeRange` as described in [`PrimitiveValue::to_datetime_range`].
662    ///
663    pub fn to_datetime_range(&self) -> Result<DateTimeRange, ConvertValueError> {
664        match self {
665            Value::Primitive(v) => v.to_datetime_range(),
666            _ => Err(ConvertValueError {
667                requested: "DateTimeRange",
668                original: self.value_type(),
669                cause: None,
670            }),
671        }
672    }
673
674    /// Retrieves the primitive value as a DICOM tag.
675    pub fn to_tag(&self) -> Result<Tag, CastValueError> {
676        match self {
677            Value::Primitive(PrimitiveValue::Tags(v)) => Ok(v[0]),
678            _ => Err(CastValueError {
679                requested: "tag",
680                got: self.value_type(),
681            }),
682        }
683    }
684
685    /// Retrieves the primitive value as a [`PersonName`].
686    pub fn to_person_name(&self) -> Result<PersonName<'_>, ConvertValueError> {
687        match self {
688            Value::Primitive(v) => v.to_person_name(),
689            _ => Err(ConvertValueError {
690                requested: "PersonName",
691                original: self.value_type(),
692                cause: None,
693            }),
694        }
695    }
696}
697
698/// Macro for implementing getters to single and multi-values,
699/// by delegating to `PrimitiveValue`.
700///
701/// Should be placed inside `Value`'s impl block.
702macro_rules! impl_primitive_getters {
703    ($name_single: ident, $name_multi: ident, $variant: ident, $ret: ty) => {
704        /// Get a single value of the requested type.
705        ///
706        /// If it contains multiple values,
707        /// only the first one is returned.
708        /// An error is returned if the variant is not compatible.
709        pub fn $name_single(&self) -> Result<$ret, CastValueError> {
710            match self {
711                Value::Primitive(v) => v.$name_single(),
712                value => Err(CastValueError {
713                    requested: stringify!($name_single),
714                    got: value.value_type(),
715                }),
716            }
717        }
718
719        /// Get a sequence of values of the requested type without copying.
720        ///
721        /// An error is returned if the variant is not compatible.
722        pub fn $name_multi(&self) -> Result<&[$ret], CastValueError> {
723            match self {
724                Value::Primitive(v) => v.$name_multi(),
725                value => Err(CastValueError {
726                    requested: stringify!($name_multi),
727                    got: value.value_type(),
728                }),
729            }
730        }
731    };
732}
733
734impl<I, P> Value<I, P> {
735    /// Get a single string value.
736    ///
737    /// If it contains multiple strings,
738    /// only the first one is returned.
739    ///
740    /// An error is returned if the variant is not compatible.
741    ///
742    /// To enable conversions of other variants to a textual representation,
743    /// see [`to_str()`] instead.
744    ///
745    /// [`to_str()`]: #method.to_str
746    pub fn string(&self) -> Result<&str, CastValueError> {
747        match self {
748            Value::Primitive(v) => v.string(),
749            _ => Err(CastValueError {
750                requested: "string",
751                got: self.value_type(),
752            }),
753        }
754    }
755
756    /// Get the inner sequence of string values
757    /// if the variant is either `Str` or `Strs`.
758    ///
759    /// An error is returned if the variant is not compatible.
760    ///
761    /// To enable conversions of other variants to a textual representation,
762    /// see [`to_str()`] instead.
763    ///
764    /// [`to_str()`]: #method.to_str
765    pub fn strings(&self) -> Result<&[String], CastValueError> {
766        match self {
767            Value::Primitive(v) => v.strings(),
768            _ => Err(CastValueError {
769                requested: "strings",
770                got: self.value_type(),
771            }),
772        }
773    }
774
775    impl_primitive_getters!(tag, tags, Tags, Tag);
776    impl_primitive_getters!(date, dates, Date, DicomDate);
777    impl_primitive_getters!(time, times, Time, DicomTime);
778    impl_primitive_getters!(datetime, datetimes, DateTime, DicomDateTime);
779    impl_primitive_getters!(uint8, uint8_slice, U8, u8);
780    impl_primitive_getters!(uint16, uint16_slice, U16, u16);
781    impl_primitive_getters!(int16, int16_slice, I16, i16);
782    impl_primitive_getters!(uint32, uint32_slice, U32, u32);
783    impl_primitive_getters!(int32, int32_slice, I32, i32);
784    impl_primitive_getters!(int64, int64_slice, I64, i64);
785    impl_primitive_getters!(uint64, uint64_slice, U64, u64);
786    impl_primitive_getters!(float32, float32_slice, F32, f32);
787    impl_primitive_getters!(float64, float64_slice, F64, f64);
788}
789
790impl<I, P> From<PrimitiveValue> for Value<I, P> {
791    fn from(v: PrimitiveValue) -> Self {
792        Value::Primitive(v)
793    }
794}
795
796/// A sequence of complex data set items of type `I`.
797#[derive(Debug, Clone)]
798pub struct DataSetSequence<I> {
799    /// The item sequence.
800    items: C<I>,
801    /// The sequence length in bytes.
802    ///
803    /// The value may be [`UNDEFINED`](Length::UNDEFINED)
804    /// if the length is implicitly defined,
805    /// otherwise it should match the full byte length of all items.
806    length: Length,
807}
808
809impl<I> DataSetSequence<I> {
810    /// Construct a DICOM data sequence
811    /// using a sequence of items and a length.
812    ///
813    /// **Note:** This function does not validate the `length`
814    /// against the items.
815    /// When not sure,
816    /// `length` can be set to [`UNDEFINED`](Length::UNDEFINED)
817    /// to leave it as implicitly defined.
818    #[inline]
819    pub fn new(items: impl Into<C<I>>, length: Length) -> Self {
820        DataSetSequence {
821            items: items.into(),
822            length,
823        }
824    }
825
826    /// Construct an empty DICOM data sequence,
827    /// with the length explicitly defined to zero.
828    #[inline]
829    pub fn empty() -> Self {
830        DataSetSequence {
831            items: Default::default(),
832            length: Length(0),
833        }
834    }
835
836    /// Gets a reference to the items of a sequence.
837    #[inline]
838    pub fn items(&self) -> &[I] {
839        &self.items
840    }
841
842    /// Gets a mutable reference to the items of a sequence.
843    #[inline]
844    pub fn items_mut(&mut self) -> &mut C<I> {
845        &mut self.items
846    }
847
848    /// Obtain the number of items in the sequence.
849    #[inline]
850    pub fn multiplicity(&self) -> u32 {
851        self.items.len() as u32
852    }
853
854    /// Retrieve the sequence of items,
855    /// discarding the recorded length information.
856    #[inline]
857    pub fn into_items(self) -> C<I> {
858        self.items
859    }
860
861    /// Get the value data's length
862    /// as specified by the sequence's data element,
863    /// in bytes.
864    ///
865    /// This is equivalent to [`HasLength::length`].
866    #[inline]
867    pub fn length(&self) -> Length {
868        HasLength::length(self)
869    }
870
871    /// Shorten this sequence by removing trailing data set items
872    /// to fit the given limit.
873    #[inline]
874    pub fn truncate(&mut self, limit: usize) {
875        self.items.truncate(limit);
876    }
877}
878
879impl<I> HasLength for DataSetSequence<I> {
880    #[inline]
881    fn length(&self) -> Length {
882        self.length
883    }
884}
885
886impl<I> DicomValueType for DataSetSequence<I> {
887    #[inline]
888    fn value_type(&self) -> ValueType {
889        ValueType::DataSetSequence
890    }
891
892    #[inline]
893    fn cardinality(&self) -> usize {
894        self.items.len()
895    }
896}
897
898impl<I> From<Vec<I>> for DataSetSequence<I> {
899    /// Converts a vector of items
900    /// into a data set sequence with an undefined length.
901    #[inline]
902    fn from(items: Vec<I>) -> Self {
903        DataSetSequence {
904            items: items.into(),
905            length: Length::UNDEFINED,
906        }
907    }
908}
909
910impl<A, I> From<SmallVec<A>> for DataSetSequence<I>
911where
912    A: smallvec::Array<Item = I>,
913    C<I>: From<SmallVec<A>>,
914{
915    /// Converts a smallvec of items
916    /// into a data set sequence with an undefined length.
917    #[inline]
918    fn from(items: SmallVec<A>) -> Self {
919        DataSetSequence {
920            items: items.into(),
921            length: Length::UNDEFINED,
922        }
923    }
924}
925
926impl<I> From<[I; 1]> for DataSetSequence<I> {
927    /// Constructs a data set sequence with a single item
928    /// and an undefined length.
929    #[inline]
930    fn from([item]: [I; 1]) -> Self {
931        DataSetSequence {
932            items: smallvec::smallvec![item],
933            length: Length::UNDEFINED,
934        }
935    }
936}
937
938impl<I, P> From<DataSetSequence<I>> for Value<I, P> {
939    #[inline]
940    fn from(value: DataSetSequence<I>) -> Self {
941        Value::Sequence(value)
942    }
943}
944
945impl<I> PartialEq<DataSetSequence<I>> for DataSetSequence<I>
946where
947    I: PartialEq,
948{
949    /// This method tests for `self` and `other` values to be equal,
950    /// and is used by `==`.
951    ///
952    /// This implementation only checks for item equality,
953    /// disregarding the byte length.
954    #[inline]
955    fn eq(&self, other: &DataSetSequence<I>) -> bool {
956        self.items() == other.items()
957    }
958}
959
960/// A sequence of pixel data fragments.
961///
962/// Each fragment (of data type `P`) is
963/// an even-lengthed sequence of bytes
964/// representing the encoded pixel data.
965/// The first item of the sequence is interpreted as a basic offset table,
966/// which is defined separately.
967#[derive(Debug, Clone, PartialEq)]
968pub struct PixelFragmentSequence<P> {
969    /// The value contents of the basic offset table.
970    offset_table: C<u32>,
971    /// The sequence of pixel data fragments.
972    fragments: C<P>,
973}
974
975impl<P> PixelFragmentSequence<P> {
976    /// Construct a DICOM pixel sequence sequence value
977    /// from a basic offset table and a list of fragments.
978    ///
979    /// **Note:** This function does not validate the offset table
980    /// against the given fragments.
981    #[inline]
982    pub fn new(offset_table: impl Into<C<u32>>, fragments: impl Into<C<P>>) -> Self {
983        PixelFragmentSequence {
984            offset_table: offset_table.into(),
985            fragments: fragments.into(),
986        }
987    }
988
989    /// Construct a DICOM pixel sequence sequence value
990    /// from a list of fragments,
991    /// with an empty basic offset table.
992    #[inline]
993    pub fn new_fragments(fragments: impl Into<C<P>>) -> Self {
994        PixelFragmentSequence {
995            offset_table: Default::default(),
996            fragments: fragments.into(),
997        }
998    }
999
1000    /// Gets a reference to the pixel data fragments.
1001    ///
1002    /// This sequence does not include the offset table.
1003    #[inline]
1004    pub fn fragments(&self) -> &[P] {
1005        &self.fragments
1006    }
1007
1008    /// Gets a mutable reference to the pixel data fragments.
1009    ///
1010    /// This sequence does not include the offset table.
1011    #[inline]
1012    pub fn fragments_mut(&mut self) -> &mut C<P> {
1013        &mut self.fragments
1014    }
1015
1016    /// Retrieve the pixel data fragments,
1017    /// discarding the rest of the information.
1018    ///
1019    /// This sequence does not include the offset table.
1020    #[inline]
1021    pub fn into_fragments(self) -> C<P> {
1022        self.fragments
1023    }
1024
1025    /// Decompose the sequence into its constituent parts:
1026    /// the basic offset table and the pixel data fragments.
1027    pub fn into_parts(self) -> (C<u32>, C<P>) {
1028        (self.offset_table, self.fragments)
1029    }
1030
1031    /// Gets a reference to the encapsulated pixel data's offset table.
1032    pub fn offset_table(&self) -> &[u32] {
1033        &self.offset_table
1034    }
1035
1036    /// Gets a mutable reference to the encapsulated pixel data's offset table.
1037    pub fn offset_table_mut(&mut self) -> &mut C<u32> {
1038        &mut self.offset_table
1039    }
1040
1041    /// Get the value data's length
1042    /// as specified by the sequence's data element,
1043    /// in bytes.
1044    ///
1045    /// This is equivalent to [`HasLength::length`].
1046    #[inline]
1047    pub fn length(&self) -> Length {
1048        HasLength::length(self)
1049    }
1050
1051    /// Shorten this sequence by removing trailing fragments
1052    /// to fit the given limit.
1053    ///
1054    /// Note that this operations does not affect the basic offset table.
1055    #[inline]
1056    pub fn truncate(&mut self, limit: usize) {
1057        self.fragments.truncate(limit);
1058    }
1059}
1060
1061impl<T, F, P> From<(T, F)> for PixelFragmentSequence<P>
1062where
1063    T: Into<C<u32>>,
1064    F: Into<C<P>>,
1065{
1066    /// Construct a pixel data fragment sequence,
1067    /// interpreting the first tuple element as a basic offset table
1068    /// and the second element as the vector of fragments.
1069    ///
1070    /// **Note:** This function does not validate the offset table
1071    /// against the given fragments.
1072    fn from((offset_table, fragments): (T, F)) -> Self {
1073        PixelFragmentSequence::new(offset_table, fragments)
1074    }
1075}
1076
1077impl<I, P> From<PixelFragmentSequence<P>> for Value<I, P> {
1078    #[inline]
1079    fn from(value: PixelFragmentSequence<P>) -> Self {
1080        Value::PixelSequence(value)
1081    }
1082}
1083
1084impl<P> HasLength for PixelFragmentSequence<P> {
1085    /// In standard DICOM,
1086    /// encapsulated pixel data is always defined by
1087    /// a pixel data element with an undefined length.
1088    #[inline]
1089    fn length(&self) -> Length {
1090        Length::UNDEFINED
1091    }
1092}
1093
1094impl<P> DicomValueType for PixelFragmentSequence<P> {
1095    #[inline]
1096    fn value_type(&self) -> ValueType {
1097        ValueType::PixelSequence
1098    }
1099
1100    #[inline]
1101    fn cardinality(&self) -> usize {
1102        1
1103    }
1104}
1105
1106#[cfg(test)]
1107mod tests {
1108    use super::*;
1109    use crate::dicom_value;
1110    use smallvec::smallvec;
1111
1112    #[test]
1113    fn to_int() {
1114        let value = Value::new(dicom_value!(I32, [1, 2, 5]));
1115        assert_eq!(value.to_int::<u32>().unwrap(), 1);
1116        assert_eq!(value.to_int::<i32>().unwrap(), 1);
1117        assert_eq!(value.to_int::<u16>().unwrap(), 1);
1118        assert_eq!(value.to_int::<i16>().unwrap(), 1);
1119        assert_eq!(value.to_int::<u64>().unwrap(), 1);
1120        assert_eq!(value.to_int::<i64>().unwrap(), 1);
1121
1122        assert_eq!(value.to_multi_int::<i32>().unwrap(), vec![1, 2, 5]);
1123        assert_eq!(value.to_multi_int::<u32>().unwrap(), vec![1, 2, 5]);
1124
1125        // sequence values can't be turned to an int
1126        let value = Value::<EmptyObject, _>::new_sequence(smallvec![], Length::UNDEFINED);
1127
1128        assert!(matches!(
1129            value.to_int::<u32>(),
1130            Err(ConvertValueError {
1131                requested: "integer",
1132                original: ValueType::DataSetSequence,
1133                ..
1134            })
1135        ));
1136    }
1137
1138    #[test]
1139    fn to_float() {
1140        let value = Value::new(dicom_value!(F64, [1., 2., 5.]));
1141        assert_eq!(value.to_float32().unwrap(), 1.);
1142        assert_eq!(value.to_float64().unwrap(), 1.);
1143
1144        assert_eq!(value.to_multi_float32().unwrap(), vec![1., 2., 5.]);
1145        assert_eq!(value.to_multi_float64().unwrap(), vec![1., 2., 5.]);
1146
1147        // sequence values can't be turned to a number
1148        let value = Value::<EmptyObject, _>::new_sequence(smallvec![], Length::UNDEFINED);
1149
1150        assert!(matches!(
1151            value.to_float32(),
1152            Err(ConvertValueError {
1153                requested: "float32",
1154                original: ValueType::DataSetSequence,
1155                ..
1156            })
1157        ));
1158    }
1159
1160    #[test]
1161    fn to_date() {
1162        let expected_dates = [
1163            DicomDate::from_ymd(2021, 2, 3).unwrap(),
1164            DicomDate::from_ymd(2022, 3, 4).unwrap(),
1165            DicomDate::from_ymd(2023, 4, 5).unwrap(),
1166        ];
1167
1168        let value = Value::new(dicom_value!(Strs, ["20210203", "20220304", "20230405"]));
1169        assert_eq!(value.to_date().unwrap(), expected_dates[0],);
1170        assert_eq!(value.to_multi_date().unwrap(), &expected_dates[..]);
1171
1172        let value_pair = Value::new(dicom_value!(
1173            Date,
1174            [
1175                DicomDate::from_ymd(2021, 2, 3).unwrap(),
1176                DicomDate::from_ymd(2022, 3, 4).unwrap(),
1177            ]
1178        ));
1179
1180        assert_eq!(value_pair.to_date().unwrap(), expected_dates[0]);
1181        assert_eq!(value_pair.to_multi_date().unwrap(), &expected_dates[0..2]);
1182
1183        // cannot turn to integers
1184        assert!(matches!(
1185            value_pair.to_multi_int::<i64>(),
1186            Err(ConvertValueError {
1187                requested: "integer",
1188                original: ValueType::Date,
1189                ..
1190            })
1191        ));
1192
1193        let range_value = Value::new(dicom_value!(Str, "20210203-20220304"));
1194
1195        // can turn to range
1196        assert_eq!(
1197            range_value.to_date_range().unwrap(),
1198            DateRange::from_start_to_end(
1199                expected_dates[0].to_naive_date().unwrap(),
1200                expected_dates[1].to_naive_date().unwrap()
1201            )
1202            .unwrap()
1203        );
1204    }
1205
1206    #[test]
1207    fn getters() {
1208        assert_eq!(
1209            Value::new(dicom_value!(Strs, ["Smith^John"]))
1210                .string()
1211                .unwrap(),
1212            "Smith^John"
1213        );
1214
1215        assert_eq!(
1216            Value::new(dicom_value!(Strs, ["Smith^John"]))
1217                .strings()
1218                .unwrap(),
1219            &["Smith^John"]
1220        );
1221
1222        assert_eq!(Value::new(dicom_value!(I32, [1, 2, 5])).int32().unwrap(), 1,);
1223
1224        assert_eq!(
1225            Value::new(dicom_value!(I32, [1, 2, 5]))
1226                .int32_slice()
1227                .unwrap(),
1228            &[1, 2, 5],
1229        );
1230
1231        assert!(matches!(
1232            Value::new(dicom_value!(I32, [1, 2, 5])).uint32(),
1233            Err(CastValueError {
1234                requested: "uint32",
1235                got: ValueType::I32,
1236                ..
1237            })
1238        ));
1239
1240        assert!(matches!(
1241            Value::new(dicom_value!(I32, [1, 2, 5])).strings(),
1242            Err(CastValueError {
1243                requested: "strings",
1244                got: ValueType::I32,
1245                ..
1246            })
1247        ));
1248
1249        assert_eq!(
1250            Value::new(PrimitiveValue::Date(smallvec![DicomDate::from_ymd(
1251                2014, 10, 12
1252            )
1253            .unwrap()]))
1254            .date()
1255            .ok(),
1256            Some(DicomDate::from_ymd(2014, 10, 12).unwrap()),
1257        );
1258
1259        assert_eq!(
1260            Value::new(PrimitiveValue::Date(
1261                smallvec![DicomDate::from_ymd(2014, 10, 12).unwrap(); 5]
1262            ))
1263            .dates()
1264            .unwrap(),
1265            &[DicomDate::from_ymd(2014, 10, 12).unwrap(); 5]
1266        );
1267
1268        assert!(matches!(
1269            Value::new(PrimitiveValue::Date(smallvec![DicomDate::from_ymd(
1270                2014, 10, 12
1271            )
1272            .unwrap()]))
1273            .time(),
1274            Err(CastValueError {
1275                requested: "time",
1276                got: ValueType::Date,
1277                ..
1278            })
1279        ));
1280    }
1281
1282    #[derive(Debug, Clone, Copy, PartialEq)]
1283    struct DummyItem(u32);
1284
1285    impl HasLength for DummyItem {
1286        fn length(&self) -> Length {
1287            Length::defined(8)
1288        }
1289    }
1290
1291    #[test]
1292    fn value_eq() {
1293        // the following declarations are equivalent
1294        let v1 = Value::<_, _>::from(PixelFragmentSequence::new(
1295            smallvec![],
1296            smallvec![vec![1, 2, 5]],
1297        ));
1298        let v2 = Value::new_pixel_sequence(smallvec![], smallvec![vec![1, 2, 5]]);
1299        assert_eq!(v1, v2);
1300        assert_eq!(v2, v1);
1301
1302        // redeclare with different type parameters
1303        let v1 = Value::<DummyItem, _>::from(PixelFragmentSequence::new(
1304            smallvec![],
1305            smallvec![vec![1, 2, 5]],
1306        ));
1307
1308        // declarations are equivalent
1309        let v3 = Value::from(PrimitiveValue::from("Something"));
1310        let v4 = Value::new(dicom_value!(Str, "Something"));
1311        let v3_2: Value = "Something".into();
1312        assert_eq!(v3, v4);
1313        assert_eq!(v3, v3_2);
1314
1315        // redeclare with different type parameters
1316        let v3: Value<DummyItem, _> = PrimitiveValue::from("Something").into();
1317
1318        let v5 = Value::from(DataSetSequence::new(
1319            vec![DummyItem(0), DummyItem(1), DummyItem(2)],
1320            Length::defined(1000),
1321        ));
1322        let v6 = Value::from(DataSetSequence::new(
1323            vec![DummyItem(0), DummyItem(1), DummyItem(2)],
1324            Length::UNDEFINED,
1325        ));
1326        assert_eq!(v5, v6);
1327
1328        assert_ne!(v1, v3);
1329        assert_ne!(v3, v1);
1330        assert_ne!(v1, v6);
1331        assert_ne!(v6, v1);
1332        assert_ne!(v3, v6);
1333        assert_ne!(v6, v3);
1334    }
1335
1336    #[test]
1337    fn data_set_sequences() {
1338        let v = DataSetSequence::new(
1339            vec![DummyItem(1), DummyItem(2), DummyItem(5)],
1340            Length::defined(24),
1341        );
1342
1343        assert_eq!(v.cardinality(), 3);
1344        assert_eq!(v.value_type(), ValueType::DataSetSequence);
1345        assert_eq!(v.items(), &[DummyItem(1), DummyItem(2), DummyItem(5)]);
1346        assert_eq!(v.length(), Length(24));
1347
1348        let v = Value::<_, [u8; 0]>::from(v);
1349        assert_eq!(v.value_type(), ValueType::DataSetSequence);
1350        assert_eq!(v.cardinality(), 3);
1351        assert_eq!(
1352            v.items(),
1353            Some(&[DummyItem(1), DummyItem(2), DummyItem(5)][..])
1354        );
1355        assert_eq!(v.primitive(), None);
1356        assert_eq!(v.fragments(), None);
1357        assert_eq!(v.offset_table(), None);
1358        assert_eq!(v.length(), Length(24));
1359
1360        // can't turn sequence to string
1361        assert!(matches!(
1362            v.to_str(),
1363            Err(ConvertValueError {
1364                original: ValueType::DataSetSequence,
1365                ..
1366            })
1367        ));
1368        // can't turn sequence to bytes
1369        assert!(matches!(
1370            v.to_bytes(),
1371            Err(ConvertValueError {
1372                requested: "bytes",
1373                original: ValueType::DataSetSequence,
1374                ..
1375            })
1376        ));
1377
1378        // can turn into items
1379        let items = v.into_items().unwrap();
1380        assert_eq!(&items[..], &[DummyItem(1), DummyItem(2), DummyItem(5)][..]);
1381    }
1382
1383    #[test]
1384    fn pixel_fragment_sequences() {
1385        let v = PixelFragmentSequence::new(vec![], vec![vec![0x55; 128]]);
1386
1387        assert_eq!(v.cardinality(), 1);
1388        assert_eq!(v.value_type(), ValueType::PixelSequence);
1389        assert_eq!(v.fragments(), &[vec![0x55; 128]]);
1390        assert!(HasLength::length(&v).is_undefined());
1391
1392        let v = Value::<EmptyObject, _>::from(v);
1393        assert_eq!(v.cardinality(), 1);
1394        assert_eq!(v.value_type(), ValueType::PixelSequence);
1395        assert_eq!(v.items(), None);
1396        assert_eq!(v.primitive(), None);
1397        assert_eq!(v.fragments(), Some(&[vec![0x55; 128]][..]));
1398        assert_eq!(v.offset_table(), Some(&[][..]));
1399        assert!(HasLength::length(&v).is_undefined());
1400
1401        // can't turn sequence to string
1402        assert!(matches!(
1403            v.to_str(),
1404            Err(ConvertValueError {
1405                requested: "string",
1406                original: ValueType::PixelSequence,
1407                ..
1408            })
1409        ));
1410
1411        // can't turn sequence to bytes
1412        assert!(matches!(
1413            v.to_bytes(),
1414            Err(ConvertValueError {
1415                requested: "bytes",
1416                original: ValueType::PixelSequence,
1417                ..
1418            })
1419        ));
1420
1421        // can turn into fragments
1422        let fragments = v.into_fragments().unwrap();
1423        assert_eq!(&fragments[..], &[vec![0x55; 128]]);
1424    }
1425}