1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum FieldType {
11 Byte,
13 Ascii,
15 Short,
17 Long,
19 Rational,
21 SByte,
23 Undefined,
25 SShort,
27 SLong,
29 SRational,
31 Float,
33 Double,
35 #[cfg(feature = "bigtiff")]
37 Long8,
38 #[cfg(feature = "bigtiff")]
40 SLong8,
41 #[cfg(feature = "bigtiff")]
43 Ifd8,
44}
45
46impl FieldType {
47 #[must_use]
52 pub fn from_code(code: u16) -> Option<Self> {
53 Some(match code {
54 1 => FieldType::Byte,
55 2 => FieldType::Ascii,
56 3 => FieldType::Short,
57 4 => FieldType::Long,
58 5 => FieldType::Rational,
59 6 => FieldType::SByte,
60 7 => FieldType::Undefined,
61 8 => FieldType::SShort,
62 9 => FieldType::SLong,
63 10 => FieldType::SRational,
64 11 => FieldType::Float,
65 12 => FieldType::Double,
66 #[cfg(feature = "bigtiff")]
67 16 => FieldType::Long8,
68 #[cfg(feature = "bigtiff")]
69 17 => FieldType::SLong8,
70 #[cfg(feature = "bigtiff")]
71 18 => FieldType::Ifd8,
72 _ => return None,
73 })
74 }
75
76 #[must_use]
78 pub fn code(self) -> u16 {
79 match self {
80 FieldType::Byte => 1,
81 FieldType::Ascii => 2,
82 FieldType::Short => 3,
83 FieldType::Long => 4,
84 FieldType::Rational => 5,
85 FieldType::SByte => 6,
86 FieldType::Undefined => 7,
87 FieldType::SShort => 8,
88 FieldType::SLong => 9,
89 FieldType::SRational => 10,
90 FieldType::Float => 11,
91 FieldType::Double => 12,
92 #[cfg(feature = "bigtiff")]
93 FieldType::Long8 => 16,
94 #[cfg(feature = "bigtiff")]
95 FieldType::SLong8 => 17,
96 #[cfg(feature = "bigtiff")]
97 FieldType::Ifd8 => 18,
98 }
99 }
100
101 #[must_use]
103 pub fn size(self) -> usize {
104 match self {
105 FieldType::Byte | FieldType::Ascii | FieldType::SByte | FieldType::Undefined => 1,
106 FieldType::Short | FieldType::SShort => 2,
107 FieldType::Long | FieldType::SLong | FieldType::Float => 4,
108 FieldType::Rational | FieldType::SRational | FieldType::Double => 8,
109 #[cfg(feature = "bigtiff")]
110 FieldType::Long8 | FieldType::SLong8 | FieldType::Ifd8 => 8,
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn field_type_codes_round_trip() {
121 for code in 1..=12u16 {
122 let ty = FieldType::from_code(code).expect("known type");
123 assert_eq!(ty.code(), code);
124 }
125 assert_eq!(FieldType::from_code(0), None);
126 assert_eq!(FieldType::from_code(13), None);
127 assert_eq!(FieldType::Rational.size(), 8);
128 assert_eq!(FieldType::Short.size(), 2);
129 }
130
131 #[cfg(feature = "bigtiff")]
132 #[test]
133 fn bigtiff_field_type_codes_round_trip() {
134 for code in 16..=18u16 {
135 let ty = FieldType::from_code(code).expect("known BigTIFF type");
136 assert_eq!(ty.code(), code);
137 }
138 assert_eq!(FieldType::from_code(19), None);
139 assert_eq!(FieldType::Long8.size(), 8);
141 assert_eq!(FieldType::SLong8.size(), 8);
142 assert_eq!(FieldType::Ifd8.size(), 8);
143 }
144
145 #[cfg(not(feature = "bigtiff"))]
147 #[test]
148 fn bigtiff_codes_unknown_without_feature() {
149 assert_eq!(FieldType::from_code(16), None);
150 assert_eq!(FieldType::from_code(17), None);
151 assert_eq!(FieldType::from_code(18), None);
152 }
153}