1use 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
26pub use either::Either;
27
28pub type C<T> = SmallVec<[T; 2]>;
30
31pub type InMemFragment = Vec<u8>;
33
34pub trait DicomValueType: HasLength {
36    fn value_type(&self) -> ValueType;
38
39    fn cardinality(&self) -> usize;
46}
47
48impl<L, R> HasLength for Either<L, R>
49where
50    L: HasLength,
51    R: HasLength,
52{
53    fn length(&self) -> Length {
54        match self {
55            Either::Left(l) => l.length(),
56            Either::Right(r) => r.length(),
57        }
58    }
59}
60
61impl<L, R> DicomValueType for Either<L, R>
62where
63    L: DicomValueType,
64    R: DicomValueType,
65{
66    fn value_type(&self) -> ValueType {
67        match self {
68            Either::Left(l) => l.value_type(),
69            Either::Right(r) => r.value_type(),
70        }
71    }
72
73    fn cardinality(&self) -> usize {
74        match self {
75            Either::Left(l) => l.cardinality(),
76            Either::Right(r) => r.cardinality(),
77        }
78    }
79}
80
81#[derive(Debug, Clone, PartialEq)]
89pub enum Value<I = EmptyObject, P = InMemFragment> {
90    Primitive(PrimitiveValue),
92    Sequence(DataSetSequence<I>),
94    PixelSequence(PixelFragmentSequence<P>),
96}
97
98impl<P> Value<EmptyObject, P> {
99    pub fn new_pixel_sequence<T>(offset_table: C<u32>, fragments: T) -> Self
113    where
114        T: Into<C<P>>,
115    {
116        Value::from(PixelFragmentSequence::new(offset_table, fragments))
117    }
118}
119
120impl<I> Value<I> {
121    #[inline]
131    pub fn new_sequence<T>(items: T, length: Length) -> Self
132    where
133        T: Into<C<I>>,
134    {
135        Self::from(DataSetSequence::new(items, length))
136    }
137}
138
139impl Value {
140    #[inline]
162    pub fn new(value: PrimitiveValue) -> Self {
163        Self::from(value)
164    }
165}
166
167impl<I, P> Value<I, P> {
168    pub fn multiplicity(&self) -> u32 {
174        match self {
175            Value::Primitive(v) => v.multiplicity(),
176            Value::Sequence(v) => v.multiplicity(),
177            Value::PixelSequence(..) => 1,
178        }
179    }
180
181    pub fn primitive(&self) -> Option<&PrimitiveValue> {
183        match self {
184            Value::Primitive(v) => Some(v),
185            _ => None,
186        }
187    }
188
189    pub fn shallow_clone(&self) -> Value<&I, &P> {
197        match self {
198            Value::Primitive(v) => Value::Primitive(v.clone()),
199            Value::Sequence(v) => Value::Sequence(DataSetSequence {
200                items: v.items.iter().collect(),
201                length: v.length,
202            }),
203            Value::PixelSequence(v) => Value::PixelSequence(PixelFragmentSequence {
204                offset_table: v.offset_table.iter().copied().collect(),
205                fragments: v.fragments.iter().collect(),
206            }),
207        }
208    }
209
210    pub fn primitive_mut(&mut self) -> Option<&mut PrimitiveValue> {
212        match self {
213            Value::Primitive(v) => Some(v),
214            _ => None,
215        }
216    }
217
218    pub fn items(&self) -> Option<&[I]> {
222        match self {
223            Value::Sequence(v) => Some(v.items()),
224            _ => None,
225        }
226    }
227
228    pub fn items_mut(&mut self) -> Option<&mut C<I>> {
232        match self {
233            Value::Sequence(v) => Some(v.items_mut()),
234            _ => None,
235        }
236    }
237
238    pub fn fragments(&self) -> Option<&[P]> {
242        match self {
243            Value::PixelSequence(v) => Some(v.fragments()),
244            _ => None,
245        }
246    }
247
248    pub fn fragments_mut(&mut self) -> Option<&mut C<P>> {
252        match self {
253            Value::PixelSequence(v) => Some(v.fragments_mut()),
254            _ => None,
255        }
256    }
257
258    pub fn into_primitive(self) -> Option<PrimitiveValue> {
260        match self {
261            Value::Primitive(v) => Some(v),
262            _ => None,
263        }
264    }
265
266    pub fn into_items(self) -> Option<C<I>> {
271        match self {
272            Value::Sequence(v) => Some(v.into_items()),
273            _ => None,
274        }
275    }
276
277    pub fn into_fragments(self) -> Option<C<P>> {
280        match self {
281            Value::PixelSequence(v) => Some(v.into_fragments()),
282            _ => None,
283        }
284    }
285
286    pub fn offset_table(&self) -> Option<&[u32]> {
290        match self {
291            Value::PixelSequence(v) => Some(v.offset_table()),
292            _ => None,
293        }
294    }
295
296    pub fn offset_table_mut(&mut self) -> Option<&mut C<u32>> {
300        match self {
301            Value::PixelSequence(v) => Some(v.offset_table_mut()),
302            _ => None,
303        }
304    }
305
306    pub fn truncate(&mut self, limit: usize) {
320        match self {
321            Value::Primitive(v) => v.truncate(limit),
322            Value::Sequence(v) => v.truncate(limit),
323            Value::PixelSequence(v) => v.truncate(limit),
324        }
325    }
326}
327
328impl<I, P> From<&str> for Value<I, P> {
329    fn from(value: &str) -> Self {
331        Value::Primitive(PrimitiveValue::from(value))
332    }
333}
334
335impl<I, P> From<String> for Value<I, P> {
336    fn from(value: String) -> Self {
338        Value::Primitive(PrimitiveValue::from(value))
339    }
340}
341
342impl<I, P> From<DicomDate> for Value<I, P> {
343    fn from(value: DicomDate) -> Self {
345        Value::Primitive(PrimitiveValue::from(value))
346    }
347}
348
349impl<I, P> From<DicomTime> for Value<I, P> {
350    fn from(value: DicomTime) -> Self {
352        Value::Primitive(PrimitiveValue::from(value))
353    }
354}
355
356impl<I, P> From<DicomDateTime> for Value<I, P> {
357    fn from(value: DicomDateTime) -> Self {
359        Value::Primitive(PrimitiveValue::from(value))
360    }
361}
362
363impl<I, P> HasLength for Value<I, P> {
364    fn length(&self) -> Length {
365        match self {
366            Value::Primitive(v) => v.length(),
367            Value::Sequence(v) => v.length(),
368            Value::PixelSequence(v) => v.length(),
369        }
370    }
371}
372
373impl<I, P> HasLength for &Value<I, P> {
374    fn length(&self) -> Length {
375        HasLength::length(*self)
376    }
377}
378
379impl<I, P> DicomValueType for Value<I, P> {
380    fn value_type(&self) -> ValueType {
381        match self {
382            Value::Primitive(v) => v.value_type(),
383            Value::Sequence(..) => ValueType::DataSetSequence,
384            Value::PixelSequence(..) => ValueType::PixelSequence,
385        }
386    }
387
388    fn cardinality(&self) -> usize {
389        match self {
390            Value::Primitive(v) => v.cardinality(),
391            Value::Sequence(DataSetSequence { items, .. }) => items.len(),
392            Value::PixelSequence { .. } => 1,
393        }
394    }
395}
396
397impl<I, P> DicomValueType for &Value<I, P> {
398    fn value_type(&self) -> ValueType {
399        DicomValueType::value_type(*self)
400    }
401
402    fn cardinality(&self) -> usize {
403        DicomValueType::cardinality(*self)
404    }
405}
406
407impl<I, P> Value<I, P>
408where
409    I: HasLength,
410{
411    pub fn to_str(&self) -> Result<Cow<'_, str>, ConvertValueError> {
422        match self {
423            Value::Primitive(prim) => Ok(prim.to_str()),
424            _ => Err(ConvertValueError {
425                requested: "string",
426                original: self.value_type(),
427                cause: None,
428            }),
429        }
430    }
431
432    pub fn to_raw_str(&self) -> Result<Cow<'_, str>, ConvertValueError> {
441        match self {
442            Value::Primitive(prim) => Ok(prim.to_raw_str()),
443            _ => Err(ConvertValueError {
444                requested: "string",
445                original: self.value_type(),
446                cause: None,
447            }),
448        }
449    }
450
451    pub fn to_multi_str(&self) -> Result<Cow<'_, [String]>, CastValueError> {
460        match self {
461            Value::Primitive(prim) => Ok(prim.to_multi_str()),
462            _ => Err(CastValueError {
463                requested: "string",
464                got: self.value_type(),
465            }),
466        }
467    }
468
469    pub fn to_bytes(&self) -> Result<Cow<'_, [u8]>, ConvertValueError> {
476        match self {
477            Value::Primitive(prim) => Ok(prim.to_bytes()),
478            _ => Err(ConvertValueError {
479                requested: "bytes",
480                original: self.value_type(),
481                cause: None,
482            }),
483        }
484    }
485
486    pub fn to_int<T>(&self) -> Result<T, ConvertValueError>
493    where
494        T: Clone,
495        T: NumCast,
496        T: FromStr<Err = std::num::ParseIntError>,
497    {
498        match self {
499            Value::Primitive(v) => v.to_int::<T>(),
500            _ => Err(ConvertValueError {
501                requested: "integer",
502                original: self.value_type(),
503                cause: None,
504            }),
505        }
506    }
507
508    pub fn to_multi_int<T>(&self) -> Result<Vec<T>, ConvertValueError>
515    where
516        T: Clone,
517        T: NumCast,
518        T: FromStr<Err = std::num::ParseIntError>,
519    {
520        match self {
521            Value::Primitive(v) => v.to_multi_int::<T>(),
522            _ => Err(ConvertValueError {
523                requested: "integer",
524                original: self.value_type(),
525                cause: None,
526            }),
527        }
528    }
529
530    pub fn to_float32(&self) -> Result<f32, ConvertValueError> {
538        match self {
539            Value::Primitive(v) => v.to_float32(),
540            _ => Err(ConvertValueError {
541                requested: "float32",
542                original: self.value_type(),
543                cause: None,
544            }),
545        }
546    }
547
548    pub fn to_multi_float32(&self) -> Result<Vec<f32>, ConvertValueError> {
556        match self {
557            Value::Primitive(v) => v.to_multi_float32(),
558            _ => Err(ConvertValueError {
559                requested: "float32",
560                original: self.value_type(),
561                cause: None,
562            }),
563        }
564    }
565
566    pub fn to_float64(&self) -> Result<f64, ConvertValueError> {
574        match self {
575            Value::Primitive(v) => v.to_float64(),
576            _ => Err(ConvertValueError {
577                requested: "float64",
578                original: self.value_type(),
579                cause: None,
580            }),
581        }
582    }
583
584    pub fn to_multi_float64(&self) -> Result<Vec<f64>, ConvertValueError> {
592        match self {
593            Value::Primitive(v) => v.to_multi_float64(),
594            _ => Err(ConvertValueError {
595                requested: "float64",
596                original: self.value_type(),
597                cause: None,
598            }),
599        }
600    }
601
602    pub fn to_date(&self) -> Result<DicomDate, ConvertValueError> {
608        match self {
609            Value::Primitive(v) => v.to_date(),
610            _ => Err(ConvertValueError {
611                requested: "DicomDate",
612                original: self.value_type(),
613                cause: None,
614            }),
615        }
616    }
617
618    pub fn to_multi_date(&self) -> Result<Vec<DicomDate>, ConvertValueError> {
624        match self {
625            Value::Primitive(v) => v.to_multi_date(),
626            _ => Err(ConvertValueError {
627                requested: "DicomDate",
628                original: self.value_type(),
629                cause: None,
630            }),
631        }
632    }
633
634    pub fn to_time(&self) -> Result<DicomTime, ConvertValueError> {
640        match self {
641            Value::Primitive(v) => v.to_time(),
642            _ => Err(ConvertValueError {
643                requested: "DicomTime",
644                original: self.value_type(),
645                cause: None,
646            }),
647        }
648    }
649
650    pub fn to_multi_time(&self) -> Result<Vec<DicomTime>, ConvertValueError> {
656        match self {
657            Value::Primitive(v) => v.to_multi_time(),
658            _ => Err(ConvertValueError {
659                requested: "DicomTime",
660                original: self.value_type(),
661                cause: None,
662            }),
663        }
664    }
665
666    pub fn to_datetime(&self) -> Result<DicomDateTime, ConvertValueError> {
672        match self {
673            Value::Primitive(v) => v.to_datetime(),
674            _ => Err(ConvertValueError {
675                requested: "DicomDateTime",
676                original: self.value_type(),
677                cause: None,
678            }),
679        }
680    }
681
682    pub fn to_multi_datetime(&self) -> Result<Vec<DicomDateTime>, ConvertValueError> {
688        match self {
689            Value::Primitive(v) => v.to_multi_datetime(),
690            _ => Err(ConvertValueError {
691                requested: "DicomDateTime",
692                original: self.value_type(),
693                cause: None,
694            }),
695        }
696    }
697
698    pub fn to_date_range(&self) -> Result<DateRange, ConvertValueError> {
704        match self {
705            Value::Primitive(v) => v.to_date_range(),
706            _ => Err(ConvertValueError {
707                requested: "DateRange",
708                original: self.value_type(),
709                cause: None,
710            }),
711        }
712    }
713
714    pub fn to_time_range(&self) -> Result<TimeRange, ConvertValueError> {
720        match self {
721            Value::Primitive(v) => v.to_time_range(),
722            _ => Err(ConvertValueError {
723                requested: "TimeRange",
724                original: self.value_type(),
725                cause: None,
726            }),
727        }
728    }
729
730    pub fn to_datetime_range(&self) -> Result<DateTimeRange, ConvertValueError> {
736        match self {
737            Value::Primitive(v) => v.to_datetime_range(),
738            _ => Err(ConvertValueError {
739                requested: "DateTimeRange",
740                original: self.value_type(),
741                cause: None,
742            }),
743        }
744    }
745
746    pub fn to_tag(&self) -> Result<Tag, CastValueError> {
748        match self {
749            Value::Primitive(PrimitiveValue::Tags(v)) => Ok(v[0]),
750            _ => Err(CastValueError {
751                requested: "tag",
752                got: self.value_type(),
753            }),
754        }
755    }
756
757    pub fn to_person_name(&self) -> Result<PersonName<'_>, ConvertValueError> {
759        match self {
760            Value::Primitive(v) => v.to_person_name(),
761            _ => Err(ConvertValueError {
762                requested: "PersonName",
763                original: self.value_type(),
764                cause: None,
765            }),
766        }
767    }
768}
769
770macro_rules! impl_primitive_getters {
775    ($name_single: ident, $name_multi: ident, $variant: ident, $ret: ty) => {
776        pub fn $name_single(&self) -> Result<$ret, CastValueError> {
782            match self {
783                Value::Primitive(v) => v.$name_single(),
784                value => Err(CastValueError {
785                    requested: stringify!($name_single),
786                    got: value.value_type(),
787                }),
788            }
789        }
790
791        pub fn $name_multi(&self) -> Result<&[$ret], CastValueError> {
795            match self {
796                Value::Primitive(v) => v.$name_multi(),
797                value => Err(CastValueError {
798                    requested: stringify!($name_multi),
799                    got: value.value_type(),
800                }),
801            }
802        }
803    };
804}
805
806impl<I, P> Value<I, P> {
807    pub fn string(&self) -> Result<&str, CastValueError> {
819        match self {
820            Value::Primitive(v) => v.string(),
821            _ => Err(CastValueError {
822                requested: "string",
823                got: self.value_type(),
824            }),
825        }
826    }
827
828    pub fn strings(&self) -> Result<&[String], CastValueError> {
838        match self {
839            Value::Primitive(v) => v.strings(),
840            _ => Err(CastValueError {
841                requested: "strings",
842                got: self.value_type(),
843            }),
844        }
845    }
846
847    impl_primitive_getters!(tag, tags, Tags, Tag);
848    impl_primitive_getters!(date, dates, Date, DicomDate);
849    impl_primitive_getters!(time, times, Time, DicomTime);
850    impl_primitive_getters!(datetime, datetimes, DateTime, DicomDateTime);
851    impl_primitive_getters!(uint8, uint8_slice, U8, u8);
852    impl_primitive_getters!(uint16, uint16_slice, U16, u16);
853    impl_primitive_getters!(int16, int16_slice, I16, i16);
854    impl_primitive_getters!(uint32, uint32_slice, U32, u32);
855    impl_primitive_getters!(int32, int32_slice, I32, i32);
856    impl_primitive_getters!(int64, int64_slice, I64, i64);
857    impl_primitive_getters!(uint64, uint64_slice, U64, u64);
858    impl_primitive_getters!(float32, float32_slice, F32, f32);
859    impl_primitive_getters!(float64, float64_slice, F64, f64);
860}
861
862impl<I, P> From<PrimitiveValue> for Value<I, P> {
863    fn from(v: PrimitiveValue) -> Self {
864        Value::Primitive(v)
865    }
866}
867
868#[derive(Debug, Clone)]
870pub struct DataSetSequence<I> {
871    items: C<I>,
873    length: Length,
879}
880
881impl<I> DataSetSequence<I> {
882    #[inline]
891    pub fn new(items: impl Into<C<I>>, length: Length) -> Self {
892        DataSetSequence {
893            items: items.into(),
894            length,
895        }
896    }
897
898    #[inline]
901    pub fn empty() -> Self {
902        DataSetSequence {
903            items: Default::default(),
904            length: Length(0),
905        }
906    }
907
908    #[inline]
910    pub fn items(&self) -> &[I] {
911        &self.items
912    }
913
914    #[inline]
916    pub fn items_mut(&mut self) -> &mut C<I> {
917        &mut self.items
918    }
919
920    #[inline]
922    pub fn multiplicity(&self) -> u32 {
923        self.items.len() as u32
924    }
925
926    #[inline]
929    pub fn into_items(self) -> C<I> {
930        self.items
931    }
932
933    #[inline]
939    pub fn length(&self) -> Length {
940        HasLength::length(self)
941    }
942
943    #[inline]
946    pub fn truncate(&mut self, limit: usize) {
947        self.items.truncate(limit);
948    }
949}
950
951impl<I> HasLength for DataSetSequence<I> {
952    #[inline]
953    fn length(&self) -> Length {
954        self.length
955    }
956}
957
958impl<I> DicomValueType for DataSetSequence<I> {
959    #[inline]
960    fn value_type(&self) -> ValueType {
961        ValueType::DataSetSequence
962    }
963
964    #[inline]
965    fn cardinality(&self) -> usize {
966        self.items.len()
967    }
968}
969
970impl<I> From<Vec<I>> for DataSetSequence<I> {
971    #[inline]
974    fn from(items: Vec<I>) -> Self {
975        DataSetSequence {
976            items: items.into(),
977            length: Length::UNDEFINED,
978        }
979    }
980}
981
982impl<A, I> From<SmallVec<A>> for DataSetSequence<I>
983where
984    A: smallvec::Array<Item = I>,
985    C<I>: From<SmallVec<A>>,
986{
987    #[inline]
990    fn from(items: SmallVec<A>) -> Self {
991        DataSetSequence {
992            items: items.into(),
993            length: Length::UNDEFINED,
994        }
995    }
996}
997
998impl<I> From<[I; 1]> for DataSetSequence<I> {
999    #[inline]
1002    fn from([item]: [I; 1]) -> Self {
1003        DataSetSequence {
1004            items: smallvec::smallvec![item],
1005            length: Length::UNDEFINED,
1006        }
1007    }
1008}
1009
1010impl<I, P> From<DataSetSequence<I>> for Value<I, P> {
1011    #[inline]
1012    fn from(value: DataSetSequence<I>) -> Self {
1013        Value::Sequence(value)
1014    }
1015}
1016
1017impl<I> PartialEq<DataSetSequence<I>> for DataSetSequence<I>
1018where
1019    I: PartialEq,
1020{
1021    #[inline]
1027    fn eq(&self, other: &DataSetSequence<I>) -> bool {
1028        self.items() == other.items()
1029    }
1030}
1031
1032#[derive(Debug, Clone, PartialEq)]
1040pub struct PixelFragmentSequence<P> {
1041    offset_table: C<u32>,
1043    fragments: C<P>,
1045}
1046
1047impl<P> PixelFragmentSequence<P> {
1048    #[inline]
1054    pub fn new(offset_table: impl Into<C<u32>>, fragments: impl Into<C<P>>) -> Self {
1055        PixelFragmentSequence {
1056            offset_table: offset_table.into(),
1057            fragments: fragments.into(),
1058        }
1059    }
1060
1061    #[inline]
1065    pub fn new_fragments(fragments: impl Into<C<P>>) -> Self {
1066        PixelFragmentSequence {
1067            offset_table: Default::default(),
1068            fragments: fragments.into(),
1069        }
1070    }
1071
1072    #[inline]
1076    pub fn fragments(&self) -> &[P] {
1077        &self.fragments
1078    }
1079
1080    #[inline]
1084    pub fn fragments_mut(&mut self) -> &mut C<P> {
1085        &mut self.fragments
1086    }
1087
1088    #[inline]
1093    pub fn into_fragments(self) -> C<P> {
1094        self.fragments
1095    }
1096
1097    pub fn into_parts(self) -> (C<u32>, C<P>) {
1100        (self.offset_table, self.fragments)
1101    }
1102
1103    pub fn offset_table(&self) -> &[u32] {
1105        &self.offset_table
1106    }
1107
1108    pub fn offset_table_mut(&mut self) -> &mut C<u32> {
1110        &mut self.offset_table
1111    }
1112
1113    #[inline]
1119    pub fn length(&self) -> Length {
1120        HasLength::length(self)
1121    }
1122
1123    #[inline]
1128    pub fn truncate(&mut self, limit: usize) {
1129        self.fragments.truncate(limit);
1130    }
1131}
1132
1133impl<T, F, P> From<(T, F)> for PixelFragmentSequence<P>
1134where
1135    T: Into<C<u32>>,
1136    F: Into<C<P>>,
1137{
1138    fn from((offset_table, fragments): (T, F)) -> Self {
1145        PixelFragmentSequence::new(offset_table, fragments)
1146    }
1147}
1148
1149impl<I, P> From<PixelFragmentSequence<P>> for Value<I, P> {
1150    #[inline]
1151    fn from(value: PixelFragmentSequence<P>) -> Self {
1152        Value::PixelSequence(value)
1153    }
1154}
1155
1156impl<P> HasLength for PixelFragmentSequence<P> {
1157    #[inline]
1161    fn length(&self) -> Length {
1162        Length::UNDEFINED
1163    }
1164}
1165
1166impl<P> DicomValueType for PixelFragmentSequence<P> {
1167    #[inline]
1168    fn value_type(&self) -> ValueType {
1169        ValueType::PixelSequence
1170    }
1171
1172    #[inline]
1173    fn cardinality(&self) -> usize {
1174        1
1175    }
1176}
1177
1178#[cfg(test)]
1179mod tests {
1180    use super::*;
1181    use crate::dicom_value;
1182    use smallvec::smallvec;
1183
1184    #[test]
1185    fn to_int() {
1186        let value = Value::new(dicom_value!(I32, [1, 2, 5]));
1187        assert_eq!(value.to_int::<u32>().unwrap(), 1);
1188        assert_eq!(value.to_int::<i32>().unwrap(), 1);
1189        assert_eq!(value.to_int::<u16>().unwrap(), 1);
1190        assert_eq!(value.to_int::<i16>().unwrap(), 1);
1191        assert_eq!(value.to_int::<u64>().unwrap(), 1);
1192        assert_eq!(value.to_int::<i64>().unwrap(), 1);
1193
1194        assert_eq!(value.to_multi_int::<i32>().unwrap(), vec![1, 2, 5]);
1195        assert_eq!(value.to_multi_int::<u32>().unwrap(), vec![1, 2, 5]);
1196
1197        let value = Value::<EmptyObject, _>::new_sequence(smallvec![], Length::UNDEFINED);
1199
1200        assert!(matches!(
1201            value.to_int::<u32>(),
1202            Err(ConvertValueError {
1203                requested: "integer",
1204                original: ValueType::DataSetSequence,
1205                ..
1206            })
1207        ));
1208    }
1209
1210    #[test]
1211    fn to_float() {
1212        let value = Value::new(dicom_value!(F64, [1., 2., 5.]));
1213        assert_eq!(value.to_float32().unwrap(), 1.);
1214        assert_eq!(value.to_float64().unwrap(), 1.);
1215
1216        assert_eq!(value.to_multi_float32().unwrap(), vec![1., 2., 5.]);
1217        assert_eq!(value.to_multi_float64().unwrap(), vec![1., 2., 5.]);
1218
1219        let value = Value::<EmptyObject, _>::new_sequence(smallvec![], Length::UNDEFINED);
1221
1222        assert!(matches!(
1223            value.to_float32(),
1224            Err(ConvertValueError {
1225                requested: "float32",
1226                original: ValueType::DataSetSequence,
1227                ..
1228            })
1229        ));
1230    }
1231
1232    #[test]
1233    fn to_date() {
1234        let expected_dates = [
1235            DicomDate::from_ymd(2021, 2, 3).unwrap(),
1236            DicomDate::from_ymd(2022, 3, 4).unwrap(),
1237            DicomDate::from_ymd(2023, 4, 5).unwrap(),
1238        ];
1239
1240        let value = Value::new(dicom_value!(Strs, ["20210203", "20220304", "20230405"]));
1241        assert_eq!(value.to_date().unwrap(), expected_dates[0],);
1242        assert_eq!(value.to_multi_date().unwrap(), &expected_dates[..]);
1243
1244        let value_pair = Value::new(dicom_value!(
1245            Date,
1246            [
1247                DicomDate::from_ymd(2021, 2, 3).unwrap(),
1248                DicomDate::from_ymd(2022, 3, 4).unwrap(),
1249            ]
1250        ));
1251
1252        assert_eq!(value_pair.to_date().unwrap(), expected_dates[0]);
1253        assert_eq!(value_pair.to_multi_date().unwrap(), &expected_dates[0..2]);
1254
1255        assert!(matches!(
1257            value_pair.to_multi_int::<i64>(),
1258            Err(ConvertValueError {
1259                requested: "integer",
1260                original: ValueType::Date,
1261                ..
1262            })
1263        ));
1264
1265        let range_value = Value::new(dicom_value!(Str, "20210203-20220304"));
1266
1267        assert_eq!(
1269            range_value.to_date_range().unwrap(),
1270            DateRange::from_start_to_end(
1271                expected_dates[0].to_naive_date().unwrap(),
1272                expected_dates[1].to_naive_date().unwrap()
1273            )
1274            .unwrap()
1275        );
1276    }
1277
1278    #[test]
1279    fn getters() {
1280        assert_eq!(
1281            Value::new(dicom_value!(Strs, ["Smith^John"]))
1282                .string()
1283                .unwrap(),
1284            "Smith^John"
1285        );
1286
1287        assert_eq!(
1288            Value::new(dicom_value!(Strs, ["Smith^John"]))
1289                .strings()
1290                .unwrap(),
1291            &["Smith^John"]
1292        );
1293
1294        assert_eq!(Value::new(dicom_value!(I32, [1, 2, 5])).int32().unwrap(), 1,);
1295
1296        assert_eq!(
1297            Value::new(dicom_value!(I32, [1, 2, 5]))
1298                .int32_slice()
1299                .unwrap(),
1300            &[1, 2, 5],
1301        );
1302
1303        assert!(matches!(
1304            Value::new(dicom_value!(I32, [1, 2, 5])).uint32(),
1305            Err(CastValueError {
1306                requested: "uint32",
1307                got: ValueType::I32,
1308                ..
1309            })
1310        ));
1311
1312        assert!(matches!(
1313            Value::new(dicom_value!(I32, [1, 2, 5])).strings(),
1314            Err(CastValueError {
1315                requested: "strings",
1316                got: ValueType::I32,
1317                ..
1318            })
1319        ));
1320
1321        assert_eq!(
1322            Value::new(PrimitiveValue::Date(smallvec![DicomDate::from_ymd(
1323                2014, 10, 12
1324            )
1325            .unwrap()]))
1326            .date()
1327            .ok(),
1328            Some(DicomDate::from_ymd(2014, 10, 12).unwrap()),
1329        );
1330
1331        assert_eq!(
1332            Value::new(PrimitiveValue::Date(
1333                smallvec![DicomDate::from_ymd(2014, 10, 12).unwrap(); 5]
1334            ))
1335            .dates()
1336            .unwrap(),
1337            &[DicomDate::from_ymd(2014, 10, 12).unwrap(); 5]
1338        );
1339
1340        assert!(matches!(
1341            Value::new(PrimitiveValue::Date(smallvec![DicomDate::from_ymd(
1342                2014, 10, 12
1343            )
1344            .unwrap()]))
1345            .time(),
1346            Err(CastValueError {
1347                requested: "time",
1348                got: ValueType::Date,
1349                ..
1350            })
1351        ));
1352    }
1353
1354    #[derive(Debug, Clone, Copy, PartialEq)]
1355    struct DummyItem(u32);
1356
1357    impl HasLength for DummyItem {
1358        fn length(&self) -> Length {
1359            Length::defined(8)
1360        }
1361    }
1362
1363    #[test]
1364    fn value_eq() {
1365        let v1 = Value::<_, _>::from(PixelFragmentSequence::new(
1367            smallvec![],
1368            smallvec![vec![1, 2, 5]],
1369        ));
1370        let v2 = Value::new_pixel_sequence(smallvec![], smallvec![vec![1, 2, 5]]);
1371        assert_eq!(v1, v2);
1372        assert_eq!(v2, v1);
1373
1374        let v1 = Value::<DummyItem, _>::from(PixelFragmentSequence::new(
1376            smallvec![],
1377            smallvec![vec![1, 2, 5]],
1378        ));
1379
1380        let v3 = Value::from(PrimitiveValue::from("Something"));
1382        let v4 = Value::new(dicom_value!(Str, "Something"));
1383        let v3_2: Value = "Something".into();
1384        assert_eq!(v3, v4);
1385        assert_eq!(v3, v3_2);
1386
1387        let v3: Value<DummyItem, _> = PrimitiveValue::from("Something").into();
1389
1390        let v5 = Value::from(DataSetSequence::new(
1391            vec![DummyItem(0), DummyItem(1), DummyItem(2)],
1392            Length::defined(1000),
1393        ));
1394        let v6 = Value::from(DataSetSequence::new(
1395            vec![DummyItem(0), DummyItem(1), DummyItem(2)],
1396            Length::UNDEFINED,
1397        ));
1398        assert_eq!(v5, v6);
1399
1400        assert_ne!(v1, v3);
1401        assert_ne!(v3, v1);
1402        assert_ne!(v1, v6);
1403        assert_ne!(v6, v1);
1404        assert_ne!(v3, v6);
1405        assert_ne!(v6, v3);
1406    }
1407
1408    #[test]
1409    fn data_set_sequences() {
1410        let v = DataSetSequence::new(
1411            vec![DummyItem(1), DummyItem(2), DummyItem(5)],
1412            Length::defined(24),
1413        );
1414
1415        assert_eq!(v.cardinality(), 3);
1416        assert_eq!(v.value_type(), ValueType::DataSetSequence);
1417        assert_eq!(v.items(), &[DummyItem(1), DummyItem(2), DummyItem(5)]);
1418        assert_eq!(v.length(), Length(24));
1419
1420        let v = Value::<_, [u8; 0]>::from(v);
1421        assert_eq!(v.value_type(), ValueType::DataSetSequence);
1422        assert_eq!(v.cardinality(), 3);
1423        assert_eq!(
1424            v.items(),
1425            Some(&[DummyItem(1), DummyItem(2), DummyItem(5)][..])
1426        );
1427        assert_eq!(v.primitive(), None);
1428        assert_eq!(v.fragments(), None);
1429        assert_eq!(v.offset_table(), None);
1430        assert_eq!(v.length(), Length(24));
1431
1432        assert!(matches!(
1434            v.to_str(),
1435            Err(ConvertValueError {
1436                original: ValueType::DataSetSequence,
1437                ..
1438            })
1439        ));
1440        assert!(matches!(
1442            v.to_bytes(),
1443            Err(ConvertValueError {
1444                requested: "bytes",
1445                original: ValueType::DataSetSequence,
1446                ..
1447            })
1448        ));
1449
1450        let items = v.into_items().unwrap();
1452        assert_eq!(&items[..], &[DummyItem(1), DummyItem(2), DummyItem(5)][..]);
1453    }
1454
1455    #[test]
1456    fn pixel_fragment_sequences() {
1457        let v = PixelFragmentSequence::new(vec![], vec![vec![0x55; 128]]);
1458
1459        assert_eq!(v.cardinality(), 1);
1460        assert_eq!(v.value_type(), ValueType::PixelSequence);
1461        assert_eq!(v.fragments(), &[vec![0x55; 128]]);
1462        assert!(HasLength::length(&v).is_undefined());
1463
1464        let v = Value::<EmptyObject, _>::from(v);
1465        assert_eq!(v.cardinality(), 1);
1466        assert_eq!(v.value_type(), ValueType::PixelSequence);
1467        assert_eq!(v.items(), None);
1468        assert_eq!(v.primitive(), None);
1469        assert_eq!(v.fragments(), Some(&[vec![0x55; 128]][..]));
1470        assert_eq!(v.offset_table(), Some(&[][..]));
1471        assert!(HasLength::length(&v).is_undefined());
1472
1473        assert!(matches!(
1475            v.to_str(),
1476            Err(ConvertValueError {
1477                requested: "string",
1478                original: ValueType::PixelSequence,
1479                ..
1480            })
1481        ));
1482
1483        assert!(matches!(
1485            v.to_bytes(),
1486            Err(ConvertValueError {
1487                requested: "bytes",
1488                original: ValueType::PixelSequence,
1489                ..
1490            })
1491        ));
1492
1493        let fragments = v.into_fragments().unwrap();
1495        assert_eq!(&fragments[..], &[vec![0x55; 128]]);
1496    }
1497}