sqlx_pg_uint/
u128.rs

1use super::*;
2use sqlx_pg_uint_macros::UIntWrapper;
3
4use crate::UIntType;
5
6impl private::Sealed for PgU128 {}
7
8impl UIntType for PgU128 {
9    type Uint = u128;
10}
11
12#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, UIntWrapper, sqlx::FromRow)]
13/// PostgreSQL-compatible unsigned 128-bit integer
14pub struct PgU128 {
15    inner: BigDecimal,
16}
17
18impl From<PgU128> for u128 {
19    fn from(value: PgU128) -> Self {
20        value.inner.to_string().parse().unwrap()
21    }
22}
23
24impl From<u128> for PgU128 {
25    fn from(value: u128) -> Self {
26        Self {
27            inner: BigDecimal::from(value),
28        }
29    }
30}
31
32#[cfg(test)]
33mod pg_u128_tests {
34    use bigdecimal::num_bigint::BigInt;
35
36    use super::*;
37
38    #[test]
39    fn test_to_u128() {
40        let pg_u128 = PgU128::from(12678671u128);
41        assert_eq!(pg_u128.to_uint(), 12678671u128);
42        let pg_u128 = PgU128::from(0);
43        assert_eq!(pg_u128.to_uint(), 0u128);
44        let pg_u128 = PgU128::from(u128::MAX);
45        assert_eq!(pg_u128.to_uint(), u128::MAX);
46    }
47
48    #[test]
49    fn test_add() {
50        let pg_u128 = PgU128::from(12678671u128);
51        let pg_u1282 = PgU128::from(12678671u128);
52        assert_eq!((pg_u128 + pg_u1282).to_uint(), 25357342u128);
53
54        let pg_u128 = PgU128::from(0u128);
55        let pg_u1282 = PgU128::from(0u128);
56        assert_eq!((pg_u128 + pg_u1282).to_uint(), 0u128);
57    }
58
59    #[test]
60    #[should_panic]
61    fn test_add_overflow() {
62        let pg_u128 = PgU128::from(u128::MAX);
63        let pg_u1282 = PgU128::from(1u128);
64        let _ = pg_u128 + pg_u1282;
65    }
66
67    #[test]
68    #[should_panic]
69    fn test_add_underflow() {
70        let pg_u128 = PgU128::from(0u128);
71        let pg_u1282 = PgU128::from(1u128);
72        let _ = pg_u128 - pg_u1282;
73    }
74
75    #[test]
76    fn try_from_bigdecimal() {
77        let pg_u128 = PgU128::try_from(BigDecimal::from(12678671u128)).unwrap();
78        assert_eq!(pg_u128.to_uint(), 12678671u128);
79
80        let pg_u128 = PgU128::try_from(BigDecimal::from(0)).unwrap();
81        assert_eq!(pg_u128.to_uint(), 0u128);
82
83        let pg_u128 = PgU128::try_from(BigDecimal::from(u128::MAX)).unwrap();
84        assert_eq!(pg_u128.to_uint(), u128::MAX);
85
86        let pg_u128 = PgU128::try_from(BigDecimal::from(-1));
87        assert!(pg_u128.is_err());
88        let err = pg_u128.unwrap_err();
89        assert_eq!(err, Error::InvalidValue(BigDecimal::from(-1)));
90
91        let fractional = BigDecimal::from(3) / BigDecimal::from(2);
92        let pg_u128 = PgU128::try_from(fractional.clone());
93        assert_eq!(pg_u128.unwrap_err(), Error::Fractional(fractional));
94
95        let big_decimal = BigDecimal::from(BigInt::from(2).pow(128));
96        let pg_u128 = PgU128::try_from(big_decimal.clone());
97        assert_eq!(pg_u128.unwrap_err(), Error::InvalidValue(big_decimal));
98    }
99
100    #[test]
101    fn test_option_conversion() {
102        let somepguint = Some(PgU128::from(123u128));
103        let someuint = somepguint.to_option_uint();
104        assert_eq!(someuint, Some(123u128));
105
106        let pguint = PgU128::from(123);
107        let someuint = pguint.to_option_uint();
108        assert_eq!(someuint, Some(123u128));
109
110        let pguint: Option<PgU128> = None;
111        let someuint = pguint.to_option_uint();
112        assert_eq!(someuint, None::<u128>);
113    }
114}