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