sqlx_exasol/types/
uint.rs1use 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::{Decimal, ExaDataType, ExaTypeInfo},
14 value::ExaValueRef,
15};
16
17const MAX_U64_NUMERIC: u64 = 1_000_000_000_000_000_000;
20const MAX_U128_NUMERIC: u128 = 1_000_000_000_000_000_000;
21
22impl Type<Exasol> for u8 {
23 fn type_info() -> ExaTypeInfo {
24 ExaDataType::Decimal(Decimal::new(Decimal::MAX_8BIT_PRECISION, 0)).into()
25 }
26
27 fn compatible(ty: &ExaTypeInfo) -> bool {
28 <Self as Type<Exasol>>::type_info().compatible(ty)
29 }
30}
31
32impl Encode<'_, Exasol> for u8 {
33 fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
34 buf.append(self)?;
35 Ok(IsNull::No)
36 }
37
38 fn produces(&self) -> Option<ExaTypeInfo> {
39 let precision = self.checked_ilog10().unwrap_or_default() + 1;
40 Some(ExaDataType::Decimal(Decimal::new(precision, 0)).into())
41 }
42
43 fn size_hint(&self) -> usize {
44 Decimal::MAX_8BIT_PRECISION as usize
45 }
46}
47
48impl Decode<'_, Exasol> for u8 {
49 fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
50 <Self as Deserialize>::deserialize(value.value).map_err(From::from)
51 }
52}
53
54impl Type<Exasol> for u16 {
55 fn type_info() -> ExaTypeInfo {
56 ExaDataType::Decimal(Decimal::new(Decimal::MAX_16BIT_PRECISION, 0)).into()
57 }
58
59 fn compatible(ty: &ExaTypeInfo) -> bool {
60 <Self as Type<Exasol>>::type_info().compatible(ty)
61 }
62}
63
64impl Encode<'_, Exasol> for u16 {
65 fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
66 buf.append(self)?;
67 Ok(IsNull::No)
68 }
69
70 fn produces(&self) -> Option<ExaTypeInfo> {
71 let precision = self.checked_ilog10().unwrap_or_default() + 1;
72 Some(ExaDataType::Decimal(Decimal::new(precision, 0)).into())
73 }
74
75 fn size_hint(&self) -> usize {
76 Decimal::MAX_16BIT_PRECISION as usize
77 }
78}
79
80impl Decode<'_, Exasol> for u16 {
81 fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
82 <Self as Deserialize>::deserialize(value.value).map_err(From::from)
83 }
84}
85
86impl Type<Exasol> for u32 {
87 fn type_info() -> ExaTypeInfo {
88 ExaDataType::Decimal(Decimal::new(Decimal::MAX_32BIT_PRECISION, 0)).into()
89 }
90
91 fn compatible(ty: &ExaTypeInfo) -> bool {
92 <Self as Type<Exasol>>::type_info().compatible(ty)
93 }
94}
95
96impl Encode<'_, Exasol> for u32 {
97 fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
98 buf.append(self)?;
99 Ok(IsNull::No)
100 }
101
102 fn produces(&self) -> Option<ExaTypeInfo> {
103 let precision = self.checked_ilog10().unwrap_or_default() + 1;
104 Some(ExaDataType::Decimal(Decimal::new(precision, 0)).into())
105 }
106
107 fn size_hint(&self) -> usize {
108 Decimal::MAX_32BIT_PRECISION as usize
109 }
110}
111
112impl Decode<'_, Exasol> for u32 {
113 fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
114 <Self as Deserialize>::deserialize(value.value).map_err(From::from)
115 }
116}
117
118impl Type<Exasol> for u64 {
119 fn type_info() -> ExaTypeInfo {
120 ExaDataType::Decimal(Decimal::new(Decimal::MAX_64BIT_PRECISION, 0)).into()
121 }
122
123 fn compatible(ty: &ExaTypeInfo) -> bool {
124 <Self as Type<Exasol>>::type_info().compatible(ty)
125 }
126}
127
128impl Encode<'_, Exasol> for u64 {
129 fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
130 if self < &MAX_U64_NUMERIC {
131 buf.append(self)?;
132 } else {
133 buf.append(format_args!("{self}"))?;
135 };
136
137 Ok(IsNull::No)
138 }
139
140 fn produces(&self) -> Option<ExaTypeInfo> {
141 let precision = self.checked_ilog10().unwrap_or_default() + 1;
142 Some(ExaDataType::Decimal(Decimal::new(precision, 0)).into())
143 }
144
145 fn size_hint(&self) -> usize {
146 Decimal::MAX_64BIT_PRECISION as usize
147 }
148}
149
150impl Decode<'_, Exasol> for u64 {
151 fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
152 match value.value {
153 Value::Number(n) => <Self as Deserialize>::deserialize(n).map_err(From::from),
154 Value::String(s) => serde_json::from_str(s).map_err(From::from),
155 v => Err(format!("invalid u64 value: {v}").into()),
156 }
157 }
158}
159
160impl Type<Exasol> for u128 {
161 fn type_info() -> ExaTypeInfo {
162 ExaDataType::Decimal(Decimal::new(Decimal::MAX_128BIT_PRECISION, 0)).into()
163 }
164
165 fn compatible(ty: &ExaTypeInfo) -> bool {
166 <Self as Type<Exasol>>::type_info().compatible(ty)
167 }
168}
169
170impl Encode<'_, Exasol> for u128 {
171 fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
172 if self < &MAX_U128_NUMERIC {
173 buf.append(self)?;
174 } else {
175 buf.append(format_args!("{self}"))?;
177 };
178
179 Ok(IsNull::No)
180 }
181
182 fn produces(&self) -> Option<ExaTypeInfo> {
183 let precision = self.checked_ilog10().unwrap_or_default() + 1;
184 Some(ExaDataType::Decimal(Decimal::new(precision, 0)).into())
185 }
186
187 fn size_hint(&self) -> usize {
188 Decimal::MAX_128BIT_PRECISION as usize
189 }
190}
191
192impl Decode<'_, Exasol> for u128 {
193 fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
194 match value.value {
195 Value::Number(n) => <Self as Deserialize>::deserialize(n).map_err(From::from),
196 Value::String(s) => serde_json::from_str(s).map_err(From::from),
197 v => Err(format!("invalid u128 value: {v}").into()),
198 }
199 }
200}