zero_postgres/conversion/
mod.rs1mod bytes;
7mod numeric_util;
8mod primitives;
9mod row;
10mod string;
11
12pub use numeric_util::numeric_to_string;
13
14#[cfg(feature = "with-chrono")]
15mod chrono;
16#[cfg(feature = "with-rust-decimal")]
17mod decimal;
18#[cfg(feature = "with-time")]
19mod time;
20#[cfg(feature = "with-uuid")]
21mod uuid;
22
23use crate::error::{Error, Result};
24use crate::protocol::types::Oid;
25pub use row::FromRow;
26
27pub trait FromWireValue<'a>: Sized {
37 fn from_null() -> Result<Self> {
42 Err(Error::Decode("unexpected NULL value".into()))
43 }
44
45 fn from_text(oid: Oid, bytes: &'a [u8]) -> Result<Self>;
50
51 fn from_binary(oid: Oid, bytes: &'a [u8]) -> Result<Self>;
56}
57
58pub trait ToWireValue {
69 fn natural_oid(&self) -> Oid;
73
74 fn encode(&self, target_oid: Oid, buf: &mut Vec<u8>) -> Result<()>;
89}
90
91pub trait ToParams {
93 fn param_count(&self) -> usize;
95
96 fn natural_oids(&self) -> Vec<Oid>;
98
99 fn encode(&self, target_oids: &[Oid], buf: &mut Vec<u8>) -> Result<()>;
104}
105
106impl<'a, T: FromWireValue<'a>> FromWireValue<'a> for Option<T> {
109 fn from_null() -> Result<Self> {
110 Ok(None)
111 }
112
113 fn from_text(oid: Oid, bytes: &'a [u8]) -> Result<Self> {
114 T::from_text(oid, bytes).map(Some)
115 }
116
117 fn from_binary(oid: Oid, bytes: &'a [u8]) -> Result<Self> {
118 T::from_binary(oid, bytes).map(Some)
119 }
120}
121
122impl<T: ToWireValue> ToWireValue for Option<T> {
123 fn natural_oid(&self) -> Oid {
124 match self {
125 Some(v) => v.natural_oid(),
126 None => 0, }
128 }
129
130 fn encode(&self, target_oid: Oid, buf: &mut Vec<u8>) -> Result<()> {
131 match self {
132 Some(v) => v.encode(target_oid, buf),
133 None => {
134 buf.extend_from_slice(&(-1_i32).to_be_bytes());
136 Ok(())
137 }
138 }
139 }
140}
141
142impl<T: ToWireValue + ?Sized> ToWireValue for &T {
145 fn natural_oid(&self) -> Oid {
146 (*self).natural_oid()
147 }
148
149 fn encode(&self, target_oid: Oid, buf: &mut Vec<u8>) -> Result<()> {
150 (*self).encode(target_oid, buf)
151 }
152}
153
154impl ToParams for () {
157 fn param_count(&self) -> usize {
158 0
159 }
160
161 fn natural_oids(&self) -> Vec<Oid> {
162 vec![]
163 }
164
165 fn encode(&self, _target_oids: &[Oid], _buf: &mut Vec<u8>) -> Result<()> {
166 Ok(())
167 }
168}
169
170impl<T: ToParams + ?Sized> ToParams for &T {
171 fn param_count(&self) -> usize {
172 (*self).param_count()
173 }
174
175 fn natural_oids(&self) -> Vec<Oid> {
176 (*self).natural_oids()
177 }
178
179 fn encode(&self, target_oids: &[Oid], buf: &mut Vec<u8>) -> Result<()> {
180 (*self).encode(target_oids, buf)
181 }
182}
183
184macro_rules! impl_to_params {
186 ($count:expr, $($idx:tt: $T:ident),+) => {
187 impl<$($T: ToWireValue),+> ToParams for ($($T,)+) {
188 fn param_count(&self) -> usize {
189 $count
190 }
191
192 fn natural_oids(&self) -> Vec<Oid> {
193 vec![$(self.$idx.natural_oid()),+]
194 }
195
196 fn encode(&self, target_oids: &[Oid], buf: &mut Vec<u8>) -> Result<()> {
197 let mut _idx = 0;
198 $(
199 self.$idx.encode(target_oids[_idx], buf)?;
200 _idx += 1;
201 )+
202 Ok(())
203 }
204 }
205 };
206}
207
208impl_to_params!(1, 0: T0);
209impl_to_params!(2, 0: T0, 1: T1);
210impl_to_params!(3, 0: T0, 1: T1, 2: T2);
211impl_to_params!(4, 0: T0, 1: T1, 2: T2, 3: T3);
212impl_to_params!(5, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4);
213impl_to_params!(6, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5);
214impl_to_params!(7, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6);
215impl_to_params!(8, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7);
216impl_to_params!(9, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8);
217impl_to_params!(10, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9);
218impl_to_params!(11, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10);
219impl_to_params!(12, 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10, 11: T11);
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224
225 #[test]
226 fn test_option_null() {
227 assert_eq!(Option::<i32>::from_null().unwrap(), None);
228 }
229}