sqlx_exasol/types/
float.rs

1use serde::Deserialize;
2use serde_json::Value;
3use sqlx_core::{
4    decode::Decode,
5    encode::{Encode, IsNull},
6    error::BoxDynError,
7    types::Type,
8};
9
10use crate::{
11    arguments::ExaBuffer,
12    database::Exasol,
13    type_info::{ExaDataType, ExaTypeInfo},
14    value::ExaValueRef,
15};
16
17impl Type<Exasol> for f32 {
18    fn type_info() -> ExaTypeInfo {
19        ExaDataType::Double.into()
20    }
21
22    fn compatible(ty: &ExaTypeInfo) -> bool {
23        <Self as Type<Exasol>>::type_info().compatible(ty)
24    }
25}
26
27impl Encode<'_, Exasol> for f32 {
28    fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
29        // NaN is treated as NULL by Exasol.
30        // Infinity is not supported by Exasol but serde_json
31        // serializes it as NULL as well.
32        if self.is_finite() {
33            buf.append(self)?;
34            Ok(IsNull::No)
35        } else {
36            buf.append(())?;
37            Ok(IsNull::Yes)
38        }
39    }
40
41    fn produces(&self) -> Option<ExaTypeInfo> {
42        Some(ExaDataType::Double.into())
43    }
44}
45
46impl Decode<'_, Exasol> for f32 {
47    fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
48        match value.value {
49            Value::Number(n) => <Self as Deserialize>::deserialize(n).map_err(From::from),
50            Value::String(s) => serde_json::from_str(s).map_err(From::from),
51            v => Err(format!("invalid f32 value: {v}").into()),
52        }
53    }
54}
55
56impl Type<Exasol> for f64 {
57    fn type_info() -> ExaTypeInfo {
58        ExaDataType::Double.into()
59    }
60
61    fn compatible(ty: &ExaTypeInfo) -> bool {
62        <Self as Type<Exasol>>::type_info().compatible(ty)
63    }
64}
65
66impl Encode<'_, Exasol> for f64 {
67    fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
68        // NaN is treated as NULL by Exasol.
69        // Infinity is not supported by Exasol but serde_json
70        // serializes it as NULL as well.
71        if self.is_finite() {
72            buf.append(self)?;
73            Ok(IsNull::No)
74        } else {
75            buf.append(())?;
76            Ok(IsNull::Yes)
77        }
78    }
79
80    fn produces(&self) -> Option<ExaTypeInfo> {
81        Some(ExaDataType::Double.into())
82    }
83}
84
85impl Decode<'_, Exasol> for f64 {
86    fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
87        match value.value {
88            Value::Number(n) => <Self as Deserialize>::deserialize(n).map_err(From::from),
89            Value::String(s) => serde_json::from_str(s).map_err(From::from),
90            v => Err(format!("invalid f64 value: {v}").into()),
91        }
92    }
93}