use cratestack_core::Value;
use serde::{Deserialize, Serialize};
use crate::sqlx::encode::IsNull;
use crate::sqlx::error::BoxDynError;
use crate::sqlx::postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef, Postgres};
use crate::sqlx::types::Json as SqlxJson;
use crate::sqlx::{Decode, Encode, Type};
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Json<T>(pub T);
impl<T> Json<T> {
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> From<T> for Json<T> {
fn from(value: T) -> Self {
Json(value)
}
}
impl<T> std::ops::Deref for Json<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> std::ops::DerefMut for Json<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl Type<Postgres> for Json<Value> {
fn type_info() -> PgTypeInfo {
<SqlxJson<serde_json::Value> as Type<Postgres>>::type_info()
}
fn compatible(ty: &PgTypeInfo) -> bool {
<SqlxJson<serde_json::Value> as Type<Postgres>>::compatible(ty)
}
}
impl PgHasArrayType for Json<Value> {
fn array_type_info() -> PgTypeInfo {
<SqlxJson<serde_json::Value> as PgHasArrayType>::array_type_info()
}
fn array_compatible(ty: &PgTypeInfo) -> bool {
<SqlxJson<serde_json::Value> as PgHasArrayType>::array_compatible(ty)
}
}
impl<'q> Encode<'q, Postgres> for Json<Value> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
SqlxJson(self.0.to_plain_json()).encode_by_ref(buf)
}
}
impl<'r> Decode<'r, Postgres> for Json<Value> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
let SqlxJson(plain) = <SqlxJson<serde_json::Value> as Decode<'r, Postgres>>::decode(value)?;
Ok(Json(Value::from_plain_json(plain)))
}
}