1pub type Base64BinaryValue = String;
2pub type ByteValue = u8;
3pub type DateTimeValue = String;
4pub type DecimalValue = String;
5pub type DoubleValue = f64;
6pub type HexBinaryValue = String;
7pub type Int16Value = i16;
8pub type Int32Value = i32;
9pub type Int64Value = i64;
10pub type IntegerValue = i64;
11pub type SByteValue = i8;
12pub type SingleValue = f32;
13pub type StringValue = String;
14pub type UInt16Value = u16;
15pub type UInt32Value = u32;
16pub type UInt64Value = u64;
17
18pub use crate::units::{
19 Coordinate32Value, CoordinateValue, DecimalNumberOrPercentValue, DrawingmlAngleValue,
20 DrawingmlPercentValue, DrawingmlPercentageValue, EmuValue, FixedPercentageValue, HpsMeasureValue,
21 MeasurementOrPercentValue, PositiveCoordinate32Value, PositiveCoordinateValue,
22 PositiveDrawingmlPercentageValue, PositiveFixedPercentageValue, PositiveUniversalMeasureValue,
23 SignedHpsMeasureValue, SignedTwipsMeasureValue, TextBulletSizeDecimalValue,
24 TextBulletSizePercentValue, TextBulletSizeValue, TextFontScalePercentOrPercentStringValue,
25 TextFontSizeValue, TextPointValue, TextSpacingPercentOrPercentStringValue, TextSpacingPointValue,
26 TwipsMeasureValue, TwipsValue, UniversalMeasureValue,
27};
28
29#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, ooxmlsdk_derive::SdkEnum)]
30pub enum BooleanValue {
31 #[sdk(rename = "true")]
32 True,
33 #[sdk(rename = "false")]
34 False,
35 #[sdk(rename = "1")]
36 One,
37 #[sdk(rename = "0")]
38 #[default]
39 Zero,
40}
41
42impl BooleanValue {
43 #[inline]
44 pub const fn from_bool(value: bool) -> Self {
45 if value { Self::One } else { Self::Zero }
46 }
47
48 #[inline]
49 pub const fn as_bool(self) -> bool {
50 matches!(self, Self::True | Self::One)
51 }
52}
53
54impl From<bool> for BooleanValue {
55 #[inline]
56 fn from(value: bool) -> Self {
57 Self::from_bool(value)
58 }
59}
60
61impl From<BooleanValue> for bool {
62 #[inline]
63 fn from(value: BooleanValue) -> Self {
64 value.as_bool()
65 }
66}
67
68#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, ooxmlsdk_derive::SdkEnum)]
69pub enum OnOffValue {
70 #[sdk(rename = "true")]
71 True,
72 #[sdk(rename = "false")]
73 #[default]
74 False,
75 #[sdk(rename = "on")]
76 On,
77 #[sdk(rename = "off")]
78 Off,
79 #[sdk(rename = "1")]
80 One,
81 #[sdk(rename = "0")]
82 Zero,
83 #[sdk(rename = "")]
84 Empty,
85}
86
87impl OnOffValue {
88 #[inline]
89 pub const fn from_bool(value: bool) -> Self {
90 if value { Self::True } else { Self::False }
91 }
92
93 #[inline]
94 pub const fn as_bool(self) -> bool {
95 matches!(self, Self::True | Self::On | Self::One | Self::Empty)
96 }
97}
98
99impl From<bool> for OnOffValue {
100 #[inline]
101 fn from(value: bool) -> Self {
102 Self::from_bool(value)
103 }
104}
105
106impl From<OnOffValue> for bool {
107 #[inline]
108 fn from(value: OnOffValue) -> Self {
109 value.as_bool()
110 }
111}
112
113#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, ooxmlsdk_derive::SdkEnum)]
114pub enum TrueFalseValue {
115 #[sdk(rename = "true")]
116 True,
117 #[sdk(rename = "false")]
118 #[default]
119 False,
120 #[sdk(rename = "t")]
121 T,
122 #[sdk(rename = "f")]
123 F,
124}
125
126impl TrueFalseValue {
127 #[inline]
128 pub const fn from_bool(value: bool) -> Self {
129 if value { Self::True } else { Self::False }
130 }
131
132 #[inline]
133 pub const fn as_bool(self) -> bool {
134 matches!(self, Self::True | Self::T)
135 }
136}
137
138impl From<bool> for TrueFalseValue {
139 #[inline]
140 fn from(value: bool) -> Self {
141 Self::from_bool(value)
142 }
143}
144
145impl From<TrueFalseValue> for bool {
146 #[inline]
147 fn from(value: TrueFalseValue) -> Self {
148 value.as_bool()
149 }
150}
151
152#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, ooxmlsdk_derive::SdkEnum)]
153pub enum TrueFalseBlankValue {
154 #[sdk(rename = "true")]
155 True,
156 #[sdk(rename = "false")]
157 #[default]
158 False,
159 #[sdk(rename = "t")]
160 T,
161 #[sdk(rename = "f")]
162 F,
163 #[sdk(rename = "")]
164 Blank,
165}
166
167impl TrueFalseBlankValue {
168 #[inline]
169 pub const fn from_bool(value: bool) -> Self {
170 if value { Self::True } else { Self::False }
171 }
172
173 #[inline]
174 pub const fn as_bool(self) -> bool {
175 matches!(self, Self::True | Self::T)
176 }
177}
178
179impl From<bool> for TrueFalseBlankValue {
180 #[inline]
181 fn from(value: bool) -> Self {
182 Self::from_bool(value)
183 }
184}
185
186impl From<TrueFalseBlankValue> for bool {
187 #[inline]
188 fn from(value: TrueFalseBlankValue) -> Self {
189 value.as_bool()
190 }
191}
192
193pub trait HexBinaryValueExt {
194 fn is_valid_hex_binary(&self) -> bool;
195 fn try_get_bytes(&self) -> Option<Vec<u8>>;
196}
197
198impl<T> HexBinaryValueExt for T
199where
200 T: AsRef<str> + ?Sized,
201{
202 fn is_valid_hex_binary(&self) -> bool {
203 is_valid_hex_binary(self.as_ref())
204 }
205
206 fn try_get_bytes(&self) -> Option<Vec<u8>> {
207 hex_binary_to_bytes(self.as_ref())
208 }
209}
210
211pub fn is_valid_hex_binary(value: &str) -> bool {
212 value.len().is_multiple_of(2) && value.as_bytes().iter().all(|byte| byte.is_ascii_hexdigit())
213}
214
215pub fn hex_binary_to_bytes(value: &str) -> Option<Vec<u8>> {
216 if !is_valid_hex_binary(value) {
217 return None;
218 }
219
220 value
221 .as_bytes()
222 .chunks_exact(2)
223 .map(|pair| Some((hex_nibble(pair[0])? << 4) | hex_nibble(pair[1])?))
224 .collect()
225}
226
227pub fn hex_binary_from_bytes(bytes: impl AsRef<[u8]>) -> HexBinaryValue {
228 const HEX: &[u8; 16] = b"0123456789ABCDEF";
229 let bytes = bytes.as_ref();
230 let mut value = String::with_capacity(bytes.len() * 2);
231 for byte in bytes {
232 value.push(HEX[(byte >> 4) as usize] as char);
233 value.push(HEX[(byte & 0x0F) as usize] as char);
234 }
235 value
236}
237
238fn hex_nibble(byte: u8) -> Option<u8> {
239 match byte {
240 b'0'..=b'9' => Some(byte - b'0'),
241 b'a'..=b'f' => Some(byte - b'a' + 10),
242 b'A'..=b'F' => Some(byte - b'A' + 10),
243 _ => None,
244 }
245}