1use crate::deserialize::{self, FromSql};
2use crate::pg::{Pg, PgValue};
3use crate::serialize::{self, IsNull, Output, ToSql};
4use crate::sql_types;
5use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
6
7#[cfg(feature = "postgres_backend")]
8impl FromSql<sql_types::Oid, Pg> for u32 {
9 fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
10 let mut bytes = bytes.as_bytes();
11 bytes.read_u32::<NetworkEndian>().map_err(Into::into)
12 }
13}
14
15#[cfg(feature = "postgres_backend")]
16impl ToSql<sql_types::Oid, Pg> for u32 {
17 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
18 out.write_u32::<NetworkEndian>(*self)
19 .map(|_| IsNull::No)
20 .map_err(Into::into)
21 }
22}
23
24#[cfg(feature = "postgres_backend")]
25impl FromSql<sql_types::SmallInt, Pg> for i16 {
26 #[inline(always)]
27 fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
28 let mut bytes = value.as_bytes();
29 if bytes.len() < 2 {
30 return emit_size_error(
31 "Received less than 2 bytes while decoding an i16. \
32 Was an expression of a different type accidentally marked as SmallInt?",
33 );
34 }
35
36 if bytes.len() > 2 {
37 return emit_size_error(
38 "Received more than 2 bytes while decoding an i16. \
39 Was an Integer expression accidentally marked as SmallInt?",
40 );
41 }
42 bytes
43 .read_i16::<NetworkEndian>()
44 .map_err(|e| Box::new(e) as Box<_>)
45 }
46}
47
48#[cfg(feature = "postgres_backend")]
49impl FromSql<sql_types::Integer, Pg> for i32 {
50 #[inline(always)]
51 fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
52 let mut bytes = value.as_bytes();
53 if bytes.len() < 4 {
54 return emit_size_error(
55 "Received less than 4 bytes while decoding an i32. \
56 Was an SmallInt expression accidentally marked as Integer?",
57 );
58 }
59
60 if bytes.len() > 4 {
61 return emit_size_error(
62 "Received more than 4 bytes while decoding an i32. \
63 Was an BigInt expression accidentally marked as Integer?",
64 );
65 }
66 bytes
67 .read_i32::<NetworkEndian>()
68 .map_err(|e| Box::new(e) as Box<_>)
69 }
70}
71
72#[cold]
73#[inline(never)]
74fn emit_size_error<T>(var_name: &str) -> deserialize::Result<T> {
75 deserialize::Result::Err(var_name.into())
76}
77
78#[cfg(feature = "postgres_backend")]
79impl FromSql<sql_types::BigInt, Pg> for i64 {
80 #[inline(always)]
81 fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
82 let mut bytes = value.as_bytes();
83 if bytes.len() < 8 {
84 return emit_size_error(
85 "Received less than 8 bytes while decoding an i64. \
86 Was an Integer expression accidentally marked as BigInt?",
87 );
88 }
89
90 if bytes.len() > 8 {
91 return emit_size_error(
92 "Received more than 8 bytes while decoding an i64. \
93 Was an expression of a different type expression accidentally marked as BigInt?"
94 );
95 }
96 bytes
97 .read_i64::<NetworkEndian>()
98 .map_err(|e| Box::new(e) as Box<_>)
99 }
100}
101
102#[cfg(feature = "postgres_backend")]
103impl ToSql<sql_types::SmallInt, Pg> for i16 {
104 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
105 out.write_i16::<NetworkEndian>(*self)
106 .map(|_| IsNull::No)
107 .map_err(|e| Box::new(e) as Box<_>)
108 }
109}
110
111#[cfg(feature = "postgres_backend")]
112impl ToSql<sql_types::Integer, Pg> for i32 {
113 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
114 out.write_i32::<NetworkEndian>(*self)
115 .map(|_| IsNull::No)
116 .map_err(|e| Box::new(e) as Box<_>)
117 }
118}
119
120#[cfg(feature = "postgres_backend")]
121impl ToSql<sql_types::BigInt, Pg> for i64 {
122 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
123 out.write_i64::<NetworkEndian>(*self)
124 .map(|_| IsNull::No)
125 .map_err(|e| Box::new(e) as Box<_>)
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::query_builder::bind_collector::ByteWrapper;
133
134 #[test]
135 fn i16_to_sql() {
136 let mut buffer = Vec::new();
137 let mut bytes = Output::test(ByteWrapper(&mut buffer));
138 ToSql::<sql_types::SmallInt, Pg>::to_sql(&1i16, &mut bytes).unwrap();
139 ToSql::<sql_types::SmallInt, Pg>::to_sql(&0i16, &mut bytes).unwrap();
140 ToSql::<sql_types::SmallInt, Pg>::to_sql(&-1i16, &mut bytes).unwrap();
141 assert_eq!(buffer, vec![0, 1, 0, 0, 255, 255]);
142 }
143
144 #[test]
145 fn i32_to_sql() {
146 let mut buffer = Vec::new();
147 let mut bytes = Output::test(ByteWrapper(&mut buffer));
148 ToSql::<sql_types::Integer, Pg>::to_sql(&1i32, &mut bytes).unwrap();
149 ToSql::<sql_types::Integer, Pg>::to_sql(&0i32, &mut bytes).unwrap();
150 ToSql::<sql_types::Integer, Pg>::to_sql(&-1i32, &mut bytes).unwrap();
151 assert_eq!(buffer, vec![0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255]);
152 }
153
154 #[test]
155 fn i64_to_sql() {
156 let mut buffer = Vec::new();
157 let mut bytes = Output::test(ByteWrapper(&mut buffer));
158 ToSql::<sql_types::BigInt, Pg>::to_sql(&1i64, &mut bytes).unwrap();
159 ToSql::<sql_types::BigInt, Pg>::to_sql(&0i64, &mut bytes).unwrap();
160 ToSql::<sql_types::BigInt, Pg>::to_sql(&-1i64, &mut bytes).unwrap();
161 assert_eq!(
162 buffer,
163 vec![
164 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255,
165 255,
166 ]
167 );
168 }
169}