1#![cfg(feature = "json")]
6
7use sqlx_core::decode::Decode;
8use sqlx_core::encode::{Encode, IsNull};
9use sqlx_core::error::BoxDynError;
10use sqlx_core::types::Type;
11
12use spg_embedded::Value as EngineValue;
13
14use crate::arguments::SpgArgumentValue;
15use crate::database::Spg;
16use crate::type_info::{Kind, SpgTypeInfo};
17use crate::value::SpgValueRef;
18
19impl Type<Spg> for serde_json::Value {
20 fn type_info() -> SpgTypeInfo {
21 SpgTypeInfo::of(Kind::Json)
22 }
23 fn compatible(ty: &SpgTypeInfo) -> bool {
24 matches!(ty.kind(), Kind::Json | Kind::Text)
27 }
28}
29
30impl<'q> Encode<'q, Spg> for serde_json::Value {
31 fn encode_by_ref(
32 &self,
33 buf: &mut Vec<SpgArgumentValue<'q>>,
34 ) -> Result<IsNull, BoxDynError> {
35 let s = serde_json::to_string(self)?;
36 buf.push(SpgArgumentValue {
37 value: EngineValue::Json(s),
38 type_info: Some(<serde_json::Value as Type<Spg>>::type_info()),
39 _phantom: core::marker::PhantomData,
40 });
41 Ok(IsNull::No)
42 }
43}
44
45impl<'r> Decode<'r, Spg> for serde_json::Value {
46 fn decode(value: SpgValueRef<'r>) -> Result<Self, BoxDynError> {
47 match value.engine() {
48 EngineValue::Json(s) | EngineValue::Text(s) => {
49 serde_json::from_str(s).map_err(|e| Box::new(e) as BoxDynError)
50 }
51 other => Err(format!("cannot decode {other:?} as serde_json::Value").into()),
52 }
53 }
54}