json: Refactor Encode/Decode for serde values to be generic for DB

Since the implementation of Encode and Decode for both mysql and
postgres on serde's Value and RawValue were practically the same they
were moved to the generic json module.
This commit is contained in:
Peter Maatman 2020-04-18 13:58:23 +02:00 committed by Ryan Leckey
parent 30d13174ea
commit 1b04829c46
4 changed files with 41 additions and 38 deletions

5
Cargo.lock generated
View file

@ -125,9 +125,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.27"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991d0a1a3e790c835fd54ab41742a59251338d8c7577fe7d7f0170c7072be708"
checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d"
dependencies = [
"proc-macro2",
"quote",
@ -303,6 +303,7 @@ name = "cargo-sqlx"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"chrono",
"dotenv",
"futures 0.3.4",

View file

@ -14,18 +14,6 @@ impl Type<MySql> for JsonValue {
}
}
impl Encode<MySql> for JsonValue {
fn encode(&self, buf: &mut Vec<u8>) {
(Box::new(Json(self)) as Box<dyn Encode<MySql>>).encode(buf)
}
}
impl<'de> Decode<'de, MySql> for JsonValue {
fn decode(value: MySqlValue<'de>) -> crate::Result<Self> {
<Json<Self> as Decode<MySql>>::decode(value).map(|item| item.0)
}
}
impl<T> Type<MySql> for Json<T> {
fn type_info() -> MySqlTypeInfo {
// MySql uses the CHAR type to pass JSON data from and to the client

View file

@ -21,36 +21,12 @@ impl Type<Postgres> for JsonValue {
}
}
impl Encode<Postgres> for JsonValue {
fn encode(&self, buf: &mut PgRawBuffer) {
(Box::new(Json(self)) as Box<dyn Encode<Postgres>>).encode(buf)
}
}
impl<'de> Decode<'de, Postgres> for JsonValue {
fn decode(value: PgValue<'de>) -> crate::Result<Self> {
<Json<Self> as Decode<Postgres>>::decode(value).map(|item| item.0)
}
}
impl Type<Postgres> for &'_ JsonRawValue {
fn type_info() -> PgTypeInfo {
<Json<Self> as Type<Postgres>>::type_info()
}
}
impl Encode<Postgres> for &'_ JsonRawValue {
fn encode(&self, buf: &mut PgRawBuffer) {
(Box::new(Json(self)) as Box<dyn Encode<Postgres>>).encode(buf)
}
}
impl<'de> Decode<'de, Postgres> for &'de JsonRawValue {
fn decode(value: PgValue<'de>) -> crate::Result<Self> {
<Json<Self> as Decode<Postgres>>::decode(value).map(|item| item.0)
}
}
impl<T> Type<Postgres> for Json<T> {
fn type_info() -> PgTypeInfo {
PgTypeInfo::new(TypeId::JSONB, "JSONB")

View file

@ -43,6 +43,12 @@ pub mod ipnetwork {
#[cfg(feature = "json")]
pub mod json {
use crate::database::Database;
use crate::decode::Decode;
use crate::encode::Encode;
use crate::value::HasRawValue;
use serde_json::value::RawValue as JsonRawValue;
use serde_json::Value as JsonValue;
use std::ops::Deref;
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
@ -62,6 +68,38 @@ pub mod json {
&self.0
}
}
impl<DB> Encode<DB> for JsonValue
where
Json<Self>: Encode<DB>,
DB: Database,
{
fn encode(&self, buf: &mut DB::RawBuffer) {
<Json<Self> as Encode<DB>>::encode(&Json(self.clone()), buf)
}
}
impl<'de, DB> Decode<'de, DB> for JsonValue
where
Json<Self>: Decode<'de, DB>,
DB: Database,
{
fn decode(value: <DB as HasRawValue<'de>>::RawValue) -> crate::Result<Self> {
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
}
}
// We don't have to implement Encode for JsonRawValue because that's covered by the default
// implementation for Encode
impl<'de, DB> Decode<'de, DB> for &'de JsonRawValue
where
Json<Self>: Decode<'de, DB>,
DB: Database,
{
fn decode(value: <DB as HasRawValue<'de>>::RawValue) -> crate::Result<Self> {
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
}
}
}
#[cfg(feature = "json")]
pub use self::json::Json;