1use alloc::string::ToString;
11use alloc::vec::Vec;
12
13use super::decoder::{
14 BoolDecoder, DateVerbatimDecoder, DecimalTextDecoder, Decoder, IntDecoder,
15 IntervalVerbatimDecoder, JsonVerbatimDecoder, NullDecoder, PgByteaBinaryDecoder, RealDecoder,
16 TextDecoder, TimeVerbatimDecoder, TimestampTzVerbatimDecoder, TimestampVerbatimDecoder,
17 UuidBlob16Decoder,
18};
19use super::error::DecodeError;
20use super::scalar_helpers::{decode_pg_bool_binary, decode_pg_int_binary, decode_pg_real_binary};
21use super::source::{PgBinary, PgBinaryColumn};
22use super::type_map::{TypeMap, TypeMapDefaults};
23use super::wire_type::WireType;
24use crate::encoding::Value;
25
26impl<S, B> Decoder<PgBinary, S, B> for NullDecoder {
27 fn decode(&self, _payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
28 Ok(Value::Null)
29 }
30}
31
32impl<S, B> Decoder<PgBinary, S, B> for BoolDecoder {
37 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
38 match payload.raw {
39 None => Ok(Value::Null),
40 Some(bytes) => decode_pg_bool_binary(payload.column_name, bytes),
41 }
42 }
43}
44
45impl<S, B> Decoder<PgBinary, S, B> for IntDecoder {
50 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
51 match payload.raw {
52 None => Ok(Value::Null),
53 Some(bytes) => decode_pg_int_binary(payload.column_name, bytes),
54 }
55 }
56}
57
58impl<S, B> Decoder<PgBinary, S, B> for RealDecoder {
64 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
65 match payload.raw {
66 None => Ok(Value::Null),
67 Some(bytes) => decode_pg_real_binary(payload.column_name, bytes),
68 }
69 }
70}
71
72impl<S, B> Decoder<PgBinary, S, B> for TextDecoder
77where
78 S: From<alloc::string::String>,
79{
80 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
81 let Some(bytes) = payload.raw else {
82 return Ok(Value::Null);
83 };
84 match core::str::from_utf8(bytes) {
85 Ok(s) => Ok(Value::Text(S::from(s.to_string()))),
86 Err(_) => Err(DecodeError::InvalidUtf8 {
87 column: payload.column_name.to_string(),
88 }),
89 }
90 }
91}
92
93impl<S, B> Decoder<PgBinary, S, B> for PgByteaBinaryDecoder
98where
99 B: From<Vec<u8>>,
100{
101 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
102 let Some(bytes) = payload.raw else {
103 return Ok(Value::Null);
104 };
105 Ok(Value::Blob(B::from(bytes.to_vec())))
106 }
107}
108
109impl<S, B> Decoder<PgBinary, S, B> for UuidBlob16Decoder
116where
117 B: From<Vec<u8>>,
118{
119 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
120 let Some(bytes) = payload.raw else {
121 return Ok(Value::Null);
122 };
123 if bytes.len() == 16 {
124 Ok(Value::Blob(B::from(bytes.to_vec())))
125 } else {
126 Err(DecodeError::InvalidUuid {
127 column: payload.column_name.to_string(),
128 source_len: bytes.len(),
129 })
130 }
131 }
132}
133
134macro_rules! not_yet_impl {
144 ($decoder:ty) => {
145 impl<S, B> Decoder<PgBinary, S, B> for $decoder {
146 fn decode(&self, payload: PgBinaryColumn<'_>) -> Result<Value<S, B>, DecodeError> {
147 if payload.raw.is_none() {
148 return Ok(Value::Null);
149 }
150 Err(DecodeError::NotYetImplemented {
151 decoder: stringify!($decoder),
152 })
153 }
154 }
155 };
156}
157
158not_yet_impl!(DecimalTextDecoder);
159not_yet_impl!(TimestampVerbatimDecoder);
160not_yet_impl!(TimestampTzVerbatimDecoder);
161not_yet_impl!(DateVerbatimDecoder);
162not_yet_impl!(TimeVerbatimDecoder);
163not_yet_impl!(IntervalVerbatimDecoder);
164not_yet_impl!(JsonVerbatimDecoder);
165
166impl<S, B> TypeMapDefaults<S, B> for PgBinary
167where
168 S: From<alloc::string::String>,
169 B: From<Vec<u8>>,
170{
171 fn defaults() -> TypeMap<Self, S, B> {
172 TypeMap::new()
173 .with(WireType::Bool, BoolDecoder)
174 .with(WireType::Int, IntDecoder)
175 .with(WireType::Real, RealDecoder)
176 .with(WireType::Text, TextDecoder)
177 .with(WireType::Bytes, PgByteaBinaryDecoder)
178 .with(WireType::Uuid, UuidBlob16Decoder)
179 .with(WireType::Decimal, DecimalTextDecoder)
180 .with(WireType::Timestamp, TimestampVerbatimDecoder)
181 .with(WireType::TimestampTz, TimestampTzVerbatimDecoder)
182 .with(WireType::Date, DateVerbatimDecoder)
183 .with(WireType::Time, TimeVerbatimDecoder)
184 .with(WireType::Interval, IntervalVerbatimDecoder)
185 .with(WireType::Json, JsonVerbatimDecoder)
186 .with(WireType::Jsonb, JsonVerbatimDecoder)
187 }
188}