dashu_float/third_party/postgres/
diesel_v1.rs

1use super::Numeric;
2use crate::{fbig::FBig, repr::Repr, round::Round};
3use dashu_base::Sign;
4use diesel_v1::{
5    deserialize::{self, FromSql},
6    pg::{data_types::PgNumeric, Pg},
7    serialize::{self, Output, ToSql},
8    sql_types::Numeric as DieselNumeric,
9};
10use std::io::Write;
11
12impl FromSql<DieselNumeric, Pg> for Numeric {
13    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
14        match PgNumeric::from_sql(bytes)? {
15            PgNumeric::Positive {
16                weight,
17                scale,
18                digits,
19            } => Ok(Numeric {
20                weight,
21                is_inf: false,
22                sign: Sign::Positive,
23                dscale: scale,
24                digits,
25            }),
26            PgNumeric::Negative {
27                weight,
28                scale,
29                digits,
30            } => Ok(Numeric {
31                weight,
32                is_inf: false,
33                sign: Sign::Negative,
34                dscale: scale,
35                digits,
36            }),
37            PgNumeric::NaN => Err(Box::from("NaN is not supported in dashu")),
38        }
39    }
40}
41
42impl FromSql<DieselNumeric, Pg> for Repr<10> {
43    #[inline]
44    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
45        Ok(Numeric::from_sql(bytes)?.into())
46    }
47}
48
49impl<R: Round> FromSql<DieselNumeric, Pg> for FBig<R, 10> {
50    #[inline]
51    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
52        Ok(Numeric::from_sql(bytes)?.into())
53    }
54}
55
56fn numeric_to_sql<W: Write>(num: Numeric, out: &mut Output<W, Pg>) -> serialize::Result {
57    let num = match num {
58        Numeric {
59            is_inf: false,
60            sign: Sign::Positive,
61            weight,
62            dscale,
63            digits,
64        } => PgNumeric::Positive {
65            weight,
66            scale: dscale,
67            digits,
68        },
69        Numeric {
70            is_inf: false,
71            sign: Sign::Negative,
72            weight,
73            dscale,
74            digits,
75        } => PgNumeric::Negative {
76            weight,
77            scale: dscale,
78            digits,
79        },
80        Numeric { is_inf: true, .. } => {
81            return Err(Box::from("Infinities are not yet supported in diesel"))
82        }
83    };
84    ToSql::<DieselNumeric, Pg>::to_sql(&num, out)
85}
86
87impl<R: Round> ToSql<DieselNumeric, Pg> for FBig<R, 10> {
88    #[inline]
89    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
90        numeric_to_sql(self.try_into()?, out)
91    }
92}
93
94impl ToSql<DieselNumeric, Pg> for Repr<10> {
95    #[inline]
96    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
97        numeric_to_sql(self.try_into()?, out)
98    }
99}