From c96de85dccb09cb6064bb1151845415058bb9cc9 Mon Sep 17 00:00:00 2001 From: Peter Maatman Date: Sat, 18 Apr 2020 13:58:23 +0200 Subject: [PATCH] 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. --- Cargo.lock | 5 ++-- sqlx-core/src/mysql/types/json.rs | 12 --------- sqlx-core/src/postgres/types/json.rs | 24 ------------------ sqlx-core/src/types.rs | 38 ++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1508f4a88c..95eb948088 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/sqlx-core/src/mysql/types/json.rs b/sqlx-core/src/mysql/types/json.rs index d62c314834..5be6d68c85 100644 --- a/sqlx-core/src/mysql/types/json.rs +++ b/sqlx-core/src/mysql/types/json.rs @@ -14,18 +14,6 @@ impl Type for JsonValue { } } -impl Encode for JsonValue { - fn encode(&self, buf: &mut Vec) { - (Box::new(Json(self)) as Box>).encode(buf) - } -} - -impl<'de> Decode<'de, MySql> for JsonValue { - fn decode(value: MySqlValue<'de>) -> crate::Result { - as Decode>::decode(value).map(|item| item.0) - } -} - impl Type for Json { fn type_info() -> MySqlTypeInfo { // MySql uses the CHAR type to pass JSON data from and to the client diff --git a/sqlx-core/src/postgres/types/json.rs b/sqlx-core/src/postgres/types/json.rs index ef2b82b05c..20aeedcda4 100644 --- a/sqlx-core/src/postgres/types/json.rs +++ b/sqlx-core/src/postgres/types/json.rs @@ -21,36 +21,12 @@ impl Type for JsonValue { } } -impl Encode for JsonValue { - fn encode(&self, buf: &mut PgRawBuffer) { - (Box::new(Json(self)) as Box>).encode(buf) - } -} - -impl<'de> Decode<'de, Postgres> for JsonValue { - fn decode(value: PgValue<'de>) -> crate::Result { - as Decode>::decode(value).map(|item| item.0) - } -} - impl Type for &'_ JsonRawValue { fn type_info() -> PgTypeInfo { as Type>::type_info() } } -impl Encode for &'_ JsonRawValue { - fn encode(&self, buf: &mut PgRawBuffer) { - (Box::new(Json(self)) as Box>).encode(buf) - } -} - -impl<'de> Decode<'de, Postgres> for &'de JsonRawValue { - fn decode(value: PgValue<'de>) -> crate::Result { - as Decode>::decode(value).map(|item| item.0) - } -} - impl Type for Json { fn type_info() -> PgTypeInfo { PgTypeInfo::new(TypeId::JSONB, "JSONB") diff --git a/sqlx-core/src/types.rs b/sqlx-core/src/types.rs index 7bae04baa5..fa81786181 100644 --- a/sqlx-core/src/types.rs +++ b/sqlx-core/src/types.rs @@ -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 Encode for JsonValue + where + Json: Encode, + DB: Database, + { + fn encode(&self, buf: &mut DB::RawBuffer) { + as Encode>::encode(&Json(self.clone()), buf) + } + } + + impl<'de, DB> Decode<'de, DB> for JsonValue + where + Json: Decode<'de, DB>, + DB: Database, + { + fn decode(value: >::RawValue) -> crate::Result { + as Decode>::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: Decode<'de, DB>, + DB: Database, + { + fn decode(value: >::RawValue) -> crate::Result { + as Decode>::decode(value).map(|item| item.0) + } + } } #[cfg(feature = "json")] pub use self::json::Json;