1use crate::arguments::PgArgumentBuffer;
2use crate::types::decode::Decode;
3use crate::types::encode::{Encode, IsNull};
4use crate::value::{PgValue, PgValueFormat};
5use rbdc::Error;
6use rbs::Value;
7use std::fmt::{Display, Formatter};
8
9#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]
10#[serde(rename = "Bytea")]
11pub struct Bytea(pub Vec<u8>);
12
13impl Display for Bytea {
14 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
15 write!(f, "[len={}]", self.0.len())
16 }
17}
18
19impl Encode for Bytea {
20 fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
21 Encode::encode(self.0, buf)
22 }
23}
24
25impl Decode for Bytea {
26 fn decode(value: PgValue) -> Result<Self, Error> {
27 Ok(Self(Vec::<u8>::decode(value)?))
29 }
30}
31
32impl From<Bytea> for Value {
33 fn from(arg: Bytea) -> Self {
34 Value::Ext("Bytea", Box::new(Value::Binary(arg.0)))
35 }
36}
37
38impl Encode for &[u8] {
39 fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
40 buf.extend_from_slice(self);
41 Ok(IsNull::No)
42 }
43}
44
45impl Encode for Vec<u8> {
46 fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
47 buf.extend(self);
48 Ok(IsNull::No)
49 }
50}
51
52impl Decode for Vec<u8> {
53 fn decode(value: PgValue) -> Result<Self, Error> {
54 match value.format() {
55 PgValueFormat::Binary => value.into_bytes(),
56 PgValueFormat::Text => {
57 hex::decode(text_hex_decode_input(&value)?).map_err(|e| Error::from(e.to_string()))
58 }
59 }
60 }
61}
62
63fn text_hex_decode_input(value: &PgValue) -> Result<&[u8], Error> {
64 value
66 .as_bytes()?
67 .strip_prefix(b"\\x")
68 .ok_or("text does not start with \\x")
69 .map_err(Into::into)
70}