sqlx_postgres/types/
json.rs1use crate::decode::Decode;
2use crate::encode::{Encode, IsNull};
3use crate::error::BoxDynError;
4use crate::types::array_compatible;
5use crate::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueFormat, PgValueRef, Postgres};
6use serde::{Deserialize, Serialize};
7use serde_json::value::RawValue as JsonRawValue;
8use serde_json::Value as JsonValue;
9pub(crate) use sqlx_core::types::{Json, Type};
10
11impl<T> Type<Postgres> for Json<T> {
18 fn type_info() -> PgTypeInfo {
19 PgTypeInfo::JSONB
20 }
21
22 fn compatible(ty: &PgTypeInfo) -> bool {
23 *ty == PgTypeInfo::JSON || *ty == PgTypeInfo::JSONB
24 }
25}
26
27impl<T> PgHasArrayType for Json<T> {
28 fn array_type_info() -> PgTypeInfo {
29 PgTypeInfo::JSONB_ARRAY
30 }
31
32 fn array_compatible(ty: &PgTypeInfo) -> bool {
33 array_compatible::<Json<T>>(ty)
34 }
35}
36
37impl PgHasArrayType for JsonValue {
38 fn array_type_info() -> PgTypeInfo {
39 PgTypeInfo::JSONB_ARRAY
40 }
41
42 fn array_compatible(ty: &PgTypeInfo) -> bool {
43 array_compatible::<JsonValue>(ty)
44 }
45}
46
47impl PgHasArrayType for JsonRawValue {
48 fn array_type_info() -> PgTypeInfo {
49 PgTypeInfo::JSONB_ARRAY
50 }
51
52 fn array_compatible(ty: &PgTypeInfo) -> bool {
53 array_compatible::<JsonRawValue>(ty)
54 }
55}
56
57impl<'q, T> Encode<'q, Postgres> for Json<T>
58where
59 T: Serialize,
60{
61 fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
62 buf.patch(|buf, ty: &PgTypeInfo| {
65 if *ty == PgTypeInfo::JSON || *ty == PgTypeInfo::JSON_ARRAY {
66 buf[0] = b' ';
67 }
68 });
69
70 buf.push(1);
72
73 serde_json::to_writer(&mut **buf, &self.0)?;
75
76 Ok(IsNull::No)
77 }
78}
79
80impl<'r, T: 'r> Decode<'r, Postgres> for Json<T>
81where
82 T: Deserialize<'r>,
83{
84 fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
85 let mut buf = value.as_bytes()?;
86
87 if value.format() == PgValueFormat::Binary && value.type_info == PgTypeInfo::JSONB {
88 assert_eq!(
89 buf[0], 1,
90 "unsupported JSONB format version {}; please open an issue",
91 buf[0]
92 );
93
94 buf = &buf[1..];
95 }
96
97 serde_json::from_slice(buf).map(Json).map_err(Into::into)
98 }
99}