1use crate::{HdbError, HdbValue, OutputParameters, ParameterDescriptor, Row, Rows};
2use bigdecimal::ToPrimitive;
3use serde_db::de::{
4 ConversionError, DbValue, DbValueInto, DeserializableResultSet, DeserializableRow,
5 DeserializationError, DeserializationResult,
6};
7use std::{
8 fmt,
9 num::{ParseFloatError, ParseIntError},
10};
11
12impl DeserializableResultSet for Rows {
13 type Row = Row;
14 type Error = DeserializationError;
15
16 fn has_multiple_rows(&mut self) -> Result<bool, DeserializationError> {
17 Ok(self.len > 1)
18 }
19
20 fn next(&mut self) -> DeserializationResult<Option<Row>> {
21 Ok(self.row_iter.next())
22 }
23
24 fn number_of_fields(&self) -> usize {
25 self.metadata.len()
26 }
27
28 fn field_name(&self, i: usize) -> Option<&str> {
29 Some(self.metadata[i].displayname())
30 }
31}
32
33impl DeserializableRow for Row {
34 type Value = HdbValue<'static>;
35 type Error = DeserializationError;
36
37 fn len(&self) -> usize {
38 self.len()
39 }
40
41 fn next(&mut self) -> Option<HdbValue<'static>> {
42 self.next_value()
43 }
44
45 fn number_of_fields(&self) -> usize {
46 self.metadata().len()
47 }
48
49 fn field_name(&self, field_idx: usize) -> Option<&str> {
50 Some(self.metadata()[field_idx].displayname())
51 }
52}
53
54pub(crate) struct DeserializableOutputParameters {
55 descriptors: Vec<ParameterDescriptor>,
56 value_iter: <Vec<HdbValue<'static>> as IntoIterator>::IntoIter,
57}
58impl DeserializableOutputParameters {
59 pub(crate) fn new(op: OutputParameters) -> DeserializableOutputParameters {
60 let (descriptors, values) = op.into_descriptors_and_values();
61 DeserializableOutputParameters {
62 descriptors,
63 value_iter: values.into_iter(),
64 }
65 }
66}
67
68impl DeserializableRow for DeserializableOutputParameters {
69 type Value = HdbValue<'static>;
70 type Error = DeserializationError;
71
72 fn len(&self) -> usize {
73 self.value_iter.len()
74 }
75
76 fn next(&mut self) -> Option<HdbValue<'static>> {
77 self.value_iter.next()
78 }
79
80 fn number_of_fields(&self) -> usize {
81 self.descriptors.len()
82 }
83
84 fn field_name(&self, field_idx: usize) -> Option<&str> {
85 self.descriptors
86 .get(field_idx)
87 .and_then(ParameterDescriptor::name)
88 }
89}
90
91impl DbValue for HdbValue<'static> {
92 fn is_null(&self) -> bool {
93 matches!(*self, HdbValue::NULL)
94 }
95}
96
97impl DbValueInto<bool> for HdbValue<'static> {
98 fn try_into(self) -> Result<bool, ConversionError> {
99 match self {
100 HdbValue::BOOLEAN(b) => Ok(b),
101 HdbValue::TINYINT(1)
102 | HdbValue::SMALLINT(1)
103 | HdbValue::INT(1)
104 | HdbValue::BIGINT(1) => Ok(true),
105 HdbValue::STRING(ref s) => match s.as_ref() {
106 "true" | "TRUE" | "True" => Ok(true),
107 "false" | "FALSE" | "False" => Ok(false),
108 _ => Err(wrong_type(&self, "bool")),
109 },
110 HdbValue::TINYINT(0)
111 | HdbValue::SMALLINT(0)
112 | HdbValue::INT(0)
113 | HdbValue::BIGINT(0) => Ok(false),
114 value => Err(wrong_type(&value, "bool")),
115 }
116 }
117}
118
119impl DbValueInto<u8> for HdbValue<'static> {
120 fn try_into(self) -> Result<u8, ConversionError> {
121 match self {
122 HdbValue::TINYINT(u) => Ok(u),
123 HdbValue::SMALLINT(i) => {
124 Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u8"))?)
125 }
126 HdbValue::INT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u8"))?),
127 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "u8"))?),
128 HdbValue::DECIMAL(bigdec) => bigdec.to_u8().ok_or_else(|| decimal_range("u8")),
129 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
130 value => Err(wrong_type(&value, "u8")),
131 }
132 }
133}
134
135impl DbValueInto<u16> for HdbValue<'static> {
136 fn try_into(self) -> Result<u16, ConversionError> {
137 match self {
138 HdbValue::TINYINT(u) => Ok(u16::from(u)),
139 HdbValue::SMALLINT(i) => {
140 Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u16"))?)
141 }
142 HdbValue::INT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u16"))?),
143 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "u16"))?),
144 HdbValue::DECIMAL(bigdec) => bigdec.to_u16().ok_or_else(|| decimal_range("u16")),
145 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
146 value => Err(wrong_type(&value, "u16")),
147 }
148 }
149}
150
151impl DbValueInto<u32> for HdbValue<'static> {
152 fn try_into(self) -> Result<u32, ConversionError> {
153 match self {
154 HdbValue::TINYINT(u) => Ok(u32::from(u)),
155 HdbValue::SMALLINT(i) => {
156 Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u32"))?)
157 }
158 HdbValue::INT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u32"))?),
159 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "u32"))?),
160 HdbValue::DECIMAL(bigdec) => bigdec.to_u32().ok_or_else(|| decimal_range("u32")),
161 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
162 value => Err(wrong_type(&value, "u32")),
163 }
164 }
165}
166
167impl DbValueInto<u64> for HdbValue<'static> {
168 fn try_into(self) -> Result<u64, ConversionError> {
169 match self {
170 HdbValue::TINYINT(u) => Ok(u64::from(u)),
171 HdbValue::SMALLINT(i) => {
172 Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u64"))?)
173 }
174 HdbValue::INT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u64"))?),
175 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "u64"))?),
176 HdbValue::DECIMAL(bigdec) => bigdec.to_u64().ok_or_else(|| decimal_range("u64")),
177 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
178 value => Err(wrong_type(&value, "u64")),
179 }
180 }
181}
182
183impl DbValueInto<i8> for HdbValue<'static> {
184 fn try_into(self) -> Result<i8, ConversionError> {
185 match self {
186 HdbValue::TINYINT(i) => {
187 Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "i8"))?)
188 }
189 HdbValue::SMALLINT(i) => {
190 Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "i8"))?)
191 }
192 HdbValue::INT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "i8"))?),
193 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "i8"))?),
194 HdbValue::DECIMAL(bigdec) => bigdec.to_i8().ok_or_else(|| decimal_range("i8")),
195 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
196 value => Err(wrong_type(&value, "i8")),
197 }
198 }
199}
200
201impl DbValueInto<i16> for HdbValue<'static> {
202 fn try_into(self) -> Result<i16, ConversionError> {
203 match self {
204 HdbValue::TINYINT(u) => Ok(i16::from(u)),
205 HdbValue::SMALLINT(i) => Ok(i),
206 HdbValue::INT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i64::from(i), "u8"))?),
207 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "u8"))?),
208 HdbValue::DECIMAL(bigdec) => bigdec.to_i16().ok_or_else(|| decimal_range("i16")),
209 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
210 value => Err(wrong_type(&value, "i16")),
211 }
212 }
213}
214
215impl DbValueInto<i32> for HdbValue<'static> {
216 fn try_into(self) -> Result<i32, ConversionError> {
217 match self {
218 HdbValue::TINYINT(u) => Ok(i32::from(u)),
219 HdbValue::SMALLINT(i) => Ok(i32::from(i)),
220 HdbValue::INT(i) => Ok(i),
221 HdbValue::BIGINT(i) => Ok(num::cast(i).ok_or_else(|| number_range(i, "i32"))?),
222 HdbValue::DECIMAL(bigdec) => bigdec.to_i32().ok_or_else(|| decimal_range("i32")),
223 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
224 value => Err(wrong_type(&value, "i32")),
225 }
226 }
227}
228
229impl DbValueInto<i64> for HdbValue<'static> {
230 fn try_into(self) -> Result<i64, ConversionError> {
231 match self {
232 HdbValue::TINYINT(u) => Ok(i64::from(u)),
233 HdbValue::SMALLINT(i) => Ok(i64::from(i)),
234 HdbValue::INT(i) => Ok(i64::from(i)),
235 HdbValue::BIGINT(i) => Ok(i),
236 HdbValue::LONGDATE(ld) => Ok(*ld.ref_raw()),
237 HdbValue::SECONDDATE(sd) => Ok(*sd.ref_raw()),
238 HdbValue::DECIMAL(bigdec) => bigdec.to_i64().ok_or_else(|| decimal_range("i64")),
239 HdbValue::STRING(s) => s.parse().map_err(|e: ParseIntError| parse_int_err(&e)),
240 value => Err(wrong_type(&value, "i64")),
241 }
242 }
243}
244
245impl DbValueInto<f32> for HdbValue<'static> {
246 fn try_into(self) -> Result<f32, ConversionError> {
247 match self {
248 HdbValue::DECIMAL(bigdec) => bigdec.to_f32().ok_or_else(|| decimal_range("f32")),
249 HdbValue::REAL(f) => Ok(f),
250 HdbValue::STRING(s) => s.parse().map_err(|e: ParseFloatError| parse_float_err(&e)),
251 value => Err(wrong_type(&value, "f32")),
252 }
253 }
254}
255
256impl DbValueInto<f64> for HdbValue<'static> {
257 fn try_into(self) -> Result<f64, ConversionError> {
258 match self {
259 HdbValue::DECIMAL(bigdec) => bigdec.to_f64().ok_or_else(|| decimal_range("f64")),
260 HdbValue::DOUBLE(f) => Ok(f),
261 HdbValue::STRING(s) => s.parse().map_err(|e: ParseFloatError| parse_float_err(&e)),
262 value => Err(wrong_type(&value, "f64")),
263 }
264 }
265}
266
267impl DbValueInto<String> for HdbValue<'static> {
268 fn try_into(self) -> Result<String, ConversionError> {
269 trace!("try_into -> String");
270 match self {
271 HdbValue::NULL => Ok(String::from("<NULL>")), HdbValue::TINYINT(i) => Ok(format!("{i}")),
273 HdbValue::SMALLINT(i) => Ok(format!("{i}")),
274 HdbValue::INT(i) => Ok(format!("{i}")),
275 HdbValue::BIGINT(i) => Ok(format!("{i}")),
276 HdbValue::REAL(f) => Ok(format!("{f}")),
277 HdbValue::DOUBLE(f) => Ok(format!("{f}")),
278 HdbValue::STRING(s) => Ok(s),
279 HdbValue::DBSTRING(bytes) => {
280 Err(ConversionError::Other(Box::new(HdbError::Cesu8AsBytes {
281 bytes,
282 })))
283 }
284 HdbValue::LONGDATE(ld) => Ok(str_from(&ld)),
285 HdbValue::SECONDDATE(sd) => Ok(str_from(&sd)),
286 HdbValue::DAYDATE(date) => Ok(str_from(&date)),
287 HdbValue::SECONDTIME(time) => Ok(str_from(&time)),
288 HdbValue::DECIMAL(bigdec) => Ok(format!("{bigdec}")),
289
290 #[cfg(feature = "sync")]
291 HdbValue::SYNC_CLOB(clob) => Ok(clob
292 .into_string_if_complete()
293 .map_err(|e| ConversionError::Incomplete(e.to_string()))?),
294 #[cfg(feature = "async")]
295 HdbValue::ASYNC_CLOB(clob) => Ok(clob
296 .into_string_if_complete()
297 .map_err(|e| ConversionError::Incomplete(e.to_string()))?),
298
299 #[cfg(feature = "sync")]
300 HdbValue::SYNC_NCLOB(nclob) => Ok(nclob
301 .into_string_if_complete()
302 .map_err(|e| ConversionError::Incomplete(e.to_string()))?),
303 #[cfg(feature = "async")]
304 HdbValue::ASYNC_NCLOB(nclob) => Ok(nclob
305 .into_string_if_complete()
306 .map_err(|e| ConversionError::Incomplete(e.to_string()))?),
307
308 value => Err(wrong_type(&value, "String")),
309 }
310 }
311}
312
313impl DbValueInto<Vec<u8>> for HdbValue<'static> {
314 fn try_into(self) -> Result<Vec<u8>, ConversionError> {
315 match self {
316 #[cfg(feature = "sync")]
317 HdbValue::SYNC_BLOB(blob) => Ok(blob
318 .into_bytes_if_complete()
319 .map_err(|e| ConversionError::Incomplete(e.to_string()))?),
320
321 #[cfg(feature = "async")]
322 HdbValue::ASYNC_BLOB(blob) => Ok(blob
323 .into_bytes_if_complete()
324 .map_err(|e| ConversionError::Incomplete(e.to_string()))?),
325
326 HdbValue::BINARY(v) | HdbValue::GEOMETRY(v) | HdbValue::POINT(v) => Ok(v),
327
328 HdbValue::STRING(s) => Ok(s.into_bytes()),
329 HdbValue::DBSTRING(v) => Ok(v),
330
331 value => Err(wrong_type(&value, "Vec<u8>")),
332 }
333 }
334}
335
336fn wrong_type(tv: &HdbValue, ovt: &str) -> ConversionError {
337 ConversionError::ValueType(format!(
338 "The value {tv:?} cannot be converted into type {ovt}",
339 ))
340}
341
342fn number_range(value: i64, ovt: &str) -> ConversionError {
343 ConversionError::NumberRange(format!(
344 "The value {value:?} exceeds the number range of type {ovt}",
345 ))
346}
347
348fn decimal_range(ovt: &str) -> ConversionError {
349 ConversionError::NumberRange(format!(
350 "The given decimal value cannot be converted into a number of type {ovt}",
351 ))
352}
353
354fn parse_int_err(e: &ParseIntError) -> ConversionError {
355 ConversionError::ValueType(e.to_string())
356}
357
358fn parse_float_err(e: &ParseFloatError) -> ConversionError {
359 ConversionError::ValueType(e.to_string())
360}
361
362fn str_from<T: fmt::Display>(t: &T) -> String {
364 format!("{t}")
365}
366
367impl From<HdbError> for DeserializationError {
369 fn from(e: HdbError) -> Self {
370 Self::Usage(e.to_string())
371 }
372}