1use crate::arguments::PgArgumentBuffer;
2use crate::type_info::PgTypeInfo;
3use crate::types::decode::Decode;
4use crate::types::encode::{Encode, IsNull};
5use crate::types::TypeInfo;
6use crate::value::{PgValue, PgValueFormat};
7use rbdc::json::Json;
8use rbdc::Error;
9use rbs::Value;
10use std::io::Write;
11
12impl Encode for Json {
13 fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
14 let mut bytes = self.0.into_bytes();
15 if bytes.is_empty() {
16 bytes = "null".to_string().into_bytes();
17 }
18 buf.patch(|buf, ty: &PgTypeInfo| {
21 if *ty == PgTypeInfo::JSON || *ty == PgTypeInfo::JSON_ARRAY {
22 buf[0] = b' ';
23 }
24 });
25
26 buf.push(1);
28
29 buf.write_all(&bytes)?;
31
32 Ok(IsNull::No)
33 }
34}
35
36impl Decode for Json {
37 fn decode(value: PgValue) -> Result<Self, Error> {
38 let fmt = value.format();
39 let type_info = value.type_info;
40 let mut buf = value.value.unwrap_or_default();
41 if buf.len() == 0 {
42 return Ok(Json {
43 0: "null".to_string(),
44 });
45 }
46 if fmt == PgValueFormat::Binary && type_info == PgTypeInfo::JSONB {
47 assert_eq!(
48 buf[0], 1,
49 "unsupported JSONB format version {}; please open an issue",
50 buf[0]
51 );
52 buf.remove(0);
53 }
54 Ok(Self {
55 0: String::from_utf8_lossy(&buf).into_owned(),
56 })
57 }
58}
59
60pub fn decode_json(value: PgValue) -> Result<Value, Error> {
61 let fmt = value.format();
62 let type_info = value.type_info;
63 let mut buf = value.value.unwrap_or_default();
64 if buf.len() == 0 {
65 return Ok(Value::Null);
66 }
67 if fmt == PgValueFormat::Binary && type_info == PgTypeInfo::JSONB {
68 assert_eq!(
69 buf[0], 1,
70 "unsupported JSONB format version {}; please open an issue",
71 buf[0]
72 );
73 buf.remove(0);
74 }
75 Ok(serde_json::from_str(&String::from_utf8_lossy(&buf))
76 .map_err(|e| Error::from(e.to_string()))?)
77}
78
79pub fn encode_json(v: Value, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
80 buf.patch(|buf, ty: &PgTypeInfo| {
83 if *ty == PgTypeInfo::JSON || *ty == PgTypeInfo::JSON_ARRAY {
84 buf[0] = b' ';
85 }
86 });
87
88 buf.push(1);
90
91 buf.write_all(&v.to_string().into_bytes())?;
93
94 Ok(IsNull::No)
95}
96
97impl TypeInfo for Json {
98 fn type_info(&self) -> PgTypeInfo {
99 PgTypeInfo::JSONB
100 }
101}