1use sqlx_core::decode::Decode;
4use sqlx_core::encode::{Encode, IsNull};
5use sqlx_core::error::BoxDynError;
6use sqlx_core::types::Type;
7
8use spg_embedded::Value as EngineValue;
9
10use crate::arguments::SpgArgumentValue;
11use crate::database::Spg;
12use crate::type_info::{Kind, SpgTypeInfo};
13use crate::value::SpgValueRef;
14
15impl Type<Spg> for [u8] {
16 fn type_info() -> SpgTypeInfo {
17 SpgTypeInfo::of(Kind::Bytes)
18 }
19
20 fn compatible(ty: &SpgTypeInfo) -> bool {
21 matches!(ty.kind(), Kind::Bytes)
22 }
23}
24
25impl Type<Spg> for Vec<u8> {
26 fn type_info() -> SpgTypeInfo {
27 <[u8] as Type<Spg>>::type_info()
28 }
29
30 fn compatible(ty: &SpgTypeInfo) -> bool {
31 <[u8] as Type<Spg>>::compatible(ty)
32 }
33}
34
35impl<'q> Encode<'q, Spg> for &'q [u8] {
36 fn encode_by_ref(
37 &self,
38 buf: &mut Vec<SpgArgumentValue<'q>>,
39 ) -> Result<IsNull, BoxDynError> {
40 buf.push(SpgArgumentValue {
41 value: EngineValue::Bytes((*self).to_vec()),
42 type_info: Some(<[u8] as Type<Spg>>::type_info()),
43 _phantom: core::marker::PhantomData,
44 });
45 Ok(IsNull::No)
46 }
47}
48
49impl<'q> Encode<'q, Spg> for Vec<u8> {
50 fn encode_by_ref(
51 &self,
52 buf: &mut Vec<SpgArgumentValue<'q>>,
53 ) -> Result<IsNull, BoxDynError> {
54 buf.push(SpgArgumentValue {
55 value: EngineValue::Bytes(self.clone()),
56 type_info: Some(<Vec<u8> as Type<Spg>>::type_info()),
57 _phantom: core::marker::PhantomData,
58 });
59 Ok(IsNull::No)
60 }
61}
62
63impl<'r> Decode<'r, Spg> for Vec<u8> {
64 fn decode(value: SpgValueRef<'r>) -> Result<Self, BoxDynError> {
65 match value.engine() {
66 EngineValue::Bytes(b) => Ok(b.clone()),
67 other => Err(format!("cannot decode {other:?} as Vec<u8> / BYTEA").into()),
68 }
69 }
70}