sqlx_exasol/types/
rust_decimal.rs1use serde::Deserialize;
2use sqlx_core::{
3 decode::Decode,
4 encode::{Encode, IsNull},
5 error::BoxDynError,
6 types::Type,
7};
8
9use crate::{
10 arguments::ExaBuffer,
11 database::Exasol,
12 type_info::{Decimal, ExaDataType, ExaTypeInfo},
13 value::ExaValueRef,
14};
15
16const RUST_DECIMAL_MAX_SCALE: u32 = 28;
18
19impl Type<Exasol> for rust_decimal::Decimal {
20 fn type_info() -> ExaTypeInfo {
21 let precision = Decimal::MAX_PRECISION + RUST_DECIMAL_MAX_SCALE;
26 let decimal = Decimal::new(precision, RUST_DECIMAL_MAX_SCALE);
27 ExaDataType::Decimal(decimal).into()
28 }
29 fn compatible(ty: &ExaTypeInfo) -> bool {
30 <Self as Type<Exasol>>::type_info().compatible(ty)
31 }
32}
33
34impl Encode<'_, Exasol> for rust_decimal::Decimal {
35 fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
36 buf.append(format_args!("{self}"))?;
37 Ok(IsNull::No)
38 }
39
40 fn produces(&self) -> Option<ExaTypeInfo> {
41 let scale = self.scale();
42 let precision = self
43 .mantissa()
44 .unsigned_abs()
45 .checked_ilog10()
46 .unwrap_or_default()
47 + 1;
48 Some(ExaDataType::Decimal(Decimal::new(precision, scale)).into())
49 }
50
51 fn size_hint(&self) -> usize {
52 1 + self
54 .mantissa()
55 .unsigned_abs()
56 .checked_ilog10()
57 .unwrap_or_default() as usize
58 + 1
59 + self.scale() as usize
60 }
61}
62
63impl Decode<'_, Exasol> for rust_decimal::Decimal {
64 fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
65 <Self as Deserialize>::deserialize(value.value).map_err(From::from)
66 }
67}