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::{PgValueFormat, PgValueRef};
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: PgValueRef) -> Result<Self, Error> {
38 let fmt = value.format();
39 let type_info = value.type_info;
40 let 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 Ok(Self {
53 0: String::from_utf8_lossy(&buf[1..]).into_owned(),
54 })
55 } else {
56 Ok(Self {
57 0: String::from_utf8_lossy(&buf).into_owned(),
58 })
59 }
60 }
61}
62
63pub fn decode_json(value: PgValueRef) -> Result<Value, Error> {
64 let fmt = value.format();
65 let type_info = value.type_info;
66 let buf = value.value.unwrap_or_default();
67 if buf.len() == 0 {
68 return Ok(Value::Null);
69 }
70 if fmt == PgValueFormat::Binary && type_info == PgTypeInfo::JSONB {
71 assert_eq!(
72 buf[0], 1,
73 "unsupported JSONB format version {}; please open an issue",
74 buf[0]
75 );
76 Ok(serde_json::from_str(&String::from_utf8_lossy(&buf[1..]))
77 .map_err(|e| Error::from(e.to_string()))?)
78 } else {
79 Ok(serde_json::from_str(&String::from_utf8_lossy(&buf))
80 .map_err(|e| Error::from(e.to_string()))?)
81 }
82}
83
84pub fn encode_json(v: Value, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
85 buf.patch(|buf, ty: &PgTypeInfo| {
88 if *ty == PgTypeInfo::JSON || *ty == PgTypeInfo::JSON_ARRAY {
89 buf[0] = b' ';
90 }
91 });
92
93 buf.push(1);
95
96 buf.write_all(&v.to_string().into_bytes())?;
98
99 Ok(IsNull::No)
100}
101
102impl TypeInfo for Json {
103 fn type_info(&self) -> PgTypeInfo {
104 PgTypeInfo::JSONB
105 }
106}