sqlx_postgres/types/
int.rs1use byteorder::{BigEndian, ByteOrder};
2use std::num::{NonZeroI16, NonZeroI32, NonZeroI64};
3
4use crate::decode::Decode;
5use crate::encode::{Encode, IsNull};
6use crate::error::BoxDynError;
7use crate::types::Type;
8use crate::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueFormat, PgValueRef, Postgres};
9
10fn int_decode(value: PgValueRef<'_>) -> Result<i64, BoxDynError> {
11 Ok(match value.format() {
12 PgValueFormat::Text => value.as_str()?.parse()?,
13 PgValueFormat::Binary => {
14 let buf = value.as_bytes()?;
15
16 match buf.len() {
18 0 => {
19 return Err("Value Buffer found empty while decoding to integer type".into());
20 }
21 buf_len @ 9.. => {
22 return Err(format!(
23 "Value Buffer exceeds 8 bytes while decoding to integer type. Buffer size = {} bytes ", buf_len
24 )
25 .into());
26 }
27 _ => {}
28 }
29
30 BigEndian::read_int(buf, buf.len())
31 }
32 })
33}
34
35impl Type<Postgres> for i8 {
36 fn type_info() -> PgTypeInfo {
37 PgTypeInfo::CHAR
38 }
39}
40
41impl PgHasArrayType for i8 {
42 fn array_type_info() -> PgTypeInfo {
43 PgTypeInfo::CHAR_ARRAY
44 }
45}
46
47impl Encode<'_, Postgres> for i8 {
48 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
49 buf.extend(&self.to_be_bytes());
50
51 Ok(IsNull::No)
52 }
53}
54
55impl Decode<'_, Postgres> for i8 {
56 fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
57 match value.format() {
60 PgValueFormat::Binary => int_decode(value)?.try_into().map_err(Into::into),
61 PgValueFormat::Text => {
62 let text = value.as_str()?;
63
64 if text.is_empty() {
66 return Ok(0);
67 }
68
69 if text.starts_with('\\') {
70 return Ok(i8::from_str_radix(text.trim_start_matches('\\'), 8)?);
72 }
73
74 #[allow(clippy::cast_possible_wrap)]
76 Ok(text.as_bytes()[0] as i8)
77 }
78 }
79 }
80}
81
82impl Type<Postgres> for i16 {
83 fn type_info() -> PgTypeInfo {
84 PgTypeInfo::INT2
85 }
86}
87
88impl PgHasArrayType for i16 {
89 fn array_type_info() -> PgTypeInfo {
90 PgTypeInfo::INT2_ARRAY
91 }
92}
93
94impl Encode<'_, Postgres> for i16 {
95 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
96 buf.extend(&self.to_be_bytes());
97
98 Ok(IsNull::No)
99 }
100}
101
102impl Decode<'_, Postgres> for i16 {
103 fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
104 int_decode(value)?.try_into().map_err(Into::into)
105 }
106}
107
108impl Type<Postgres> for i32 {
109 fn type_info() -> PgTypeInfo {
110 PgTypeInfo::INT4
111 }
112}
113
114impl PgHasArrayType for i32 {
115 fn array_type_info() -> PgTypeInfo {
116 PgTypeInfo::INT4_ARRAY
117 }
118}
119
120impl Encode<'_, Postgres> for i32 {
121 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
122 buf.extend(&self.to_be_bytes());
123
124 Ok(IsNull::No)
125 }
126}
127
128impl Decode<'_, Postgres> for i32 {
129 fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
130 int_decode(value)?.try_into().map_err(Into::into)
131 }
132}
133
134impl Type<Postgres> for i64 {
135 fn type_info() -> PgTypeInfo {
136 PgTypeInfo::INT8
137 }
138}
139
140impl PgHasArrayType for i64 {
141 fn array_type_info() -> PgTypeInfo {
142 PgTypeInfo::INT8_ARRAY
143 }
144}
145
146impl Encode<'_, Postgres> for i64 {
147 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
148 buf.extend(&self.to_be_bytes());
149
150 Ok(IsNull::No)
151 }
152}
153
154impl Decode<'_, Postgres> for i64 {
155 fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
156 int_decode(value)
157 }
158}
159
160impl PgHasArrayType for NonZeroI16 {
161 fn array_type_info() -> PgTypeInfo {
162 PgTypeInfo::INT2_ARRAY
163 }
164}
165
166impl PgHasArrayType for NonZeroI32 {
167 fn array_type_info() -> PgTypeInfo {
168 PgTypeInfo::INT4_ARRAY
169 }
170}
171
172impl PgHasArrayType for NonZeroI64 {
173 fn array_type_info() -> PgTypeInfo {
174 PgTypeInfo::INT8_ARRAY
175 }
176}