From 35bf5604810373dffb1fd2e71931d22fe79de838 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Sat, 30 May 2020 18:17:51 -0700 Subject: [PATCH] fix(core): tweak serialization impls to fix offline mode --- sqlx-core/Cargo.toml | 2 +- sqlx-core/src/ext/ustr.rs | 26 +++++++++++++++++++++++++- sqlx-core/src/postgres/type_info.rs | 4 ++-- sqlx-core/src/postgres/types/array.rs | 3 +-- sqlx-core/src/postgres/types/record.rs | 3 +-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sqlx-core/Cargo.toml b/sqlx-core/Cargo.toml index f181aff00..6b2678004 100644 --- a/sqlx-core/Cargo.toml +++ b/sqlx-core/Cargo.toml @@ -72,7 +72,7 @@ parking_lot = "0.10.2" threadpool = "*" phf = { version = "0.8.0", features = [ "macros" ] } rand = { version = "0.7.3", default-features = false, optional = true, features = [ "std" ] } -serde = { version = "1.0.106", features = [ "derive" ], optional = true } +serde = { version = "1.0.106", features = [ "derive", "rc" ], optional = true } serde_json = { version = "1.0.51", features = [ "raw_value" ], optional = true } sha-1 = { version = "0.8.2", default-features = false, optional = true } sha2 = { version = "0.8.1", default-features = false, optional = true } diff --git a/sqlx-core/src/ext/ustr.rs b/sqlx-core/src/ext/ustr.rs index a6b8e1f36..29312fa29 100644 --- a/sqlx-core/src/ext/ustr.rs +++ b/sqlx-core/src/ext/ustr.rs @@ -8,7 +8,6 @@ use std::sync::Arc; // a micro-string is either a reference-counted string or a static string // this guarantees these are cheap to clone everywhere #[derive(Debug, Clone, Eq)] -#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))] pub(crate) enum UStr { Static(&'static str), Shared(Arc), @@ -75,3 +74,28 @@ impl Display for UStr { f.pad(self) } } + +// manual impls because otherwise things get a little screwy with lifetimes + +#[cfg(feature = "offline")] +impl<'de> serde::Deserialize<'de> for UStr { + fn deserialize(deserializer: D) -> Result>::Error> + where + D: serde::Deserializer<'de>, + { + Ok(String::deserialize(deserializer)?.into()) + } +} + +#[cfg(feature = "offline")] +impl serde::Serialize for UStr { + fn serialize( + &self, + serializer: S, + ) -> Result<::Ok, ::Error> + where + S: serde::Serializer, + { + serializer.serialize_str(&self) + } +} diff --git a/sqlx-core/src/postgres/type_info.rs b/sqlx-core/src/postgres/type_info.rs index f90ba9480..63257a541 100644 --- a/sqlx-core/src/postgres/type_info.rs +++ b/sqlx-core/src/postgres/type_info.rs @@ -109,7 +109,7 @@ pub(crate) enum PgType { Custom(Arc), // From [`PgTypeInfo::with_name`] - DeclareWithName(&'static str), + DeclareWithName(UStr), // NOTE: Do we want to bring back type declaration by ID? It's notoriously fragile but // someone may have a user for it @@ -194,7 +194,7 @@ impl PgTypeInfo { /// The OID for the type will be fetched from Postgres on use of /// a value of this type. The fetched OID will be cached per-connection. pub const fn with_name(name: &'static str) -> Self { - Self(PgType::DeclareWithName(name)) + Self(PgType::DeclareWithName(UStr::Static(name))) } pub(crate) const fn with_oid(oid: u32) -> Self { diff --git a/sqlx-core/src/postgres/types/array.rs b/sqlx-core/src/postgres/types/array.rs index f34ef641f..4d35747fe 100644 --- a/sqlx-core/src/postgres/types/array.rs +++ b/sqlx-core/src/postgres/types/array.rs @@ -3,7 +3,6 @@ use bytes::Buf; use crate::decode::Decode; use crate::encode::{Encode, IsNull}; use crate::error::BoxDynError; -use crate::ext::ustr::UStr; use crate::postgres::type_info::PgType; use crate::postgres::{PgArgumentBuffer, PgTypeInfo, PgValueFormat, PgValueRef, Postgres}; use crate::types::Type; @@ -49,7 +48,7 @@ where // element type match T::type_info().0 { - PgType::DeclareWithName(name) => buf.push_type_hole(&UStr::Static(name)), + PgType::DeclareWithName(name) => buf.push_type_hole(&name), ty => { buf.extend(&ty.oid().to_be_bytes()); diff --git a/sqlx-core/src/postgres/types/record.rs b/sqlx-core/src/postgres/types/record.rs index e69ed6eef..19feec6f6 100644 --- a/sqlx-core/src/postgres/types/record.rs +++ b/sqlx-core/src/postgres/types/record.rs @@ -3,7 +3,6 @@ use bytes::Buf; use crate::decode::Decode; use crate::encode::{Encode, IsNull}; use crate::error::{mismatched_types, BoxDynError}; -use crate::ext::ustr::UStr; use crate::postgres::type_info::PgType; use crate::postgres::{ PgArgumentBuffer, PgTypeInfo, PgTypeKind, PgValueFormat, PgValueRef, Postgres, @@ -44,7 +43,7 @@ impl<'a> PgRecordEncoder<'a> { if let PgType::DeclareWithName(name) = ty.0 { // push a hole for this type ID // to be filled in on query execution - self.buf.push_type_hole(&UStr::Static(name)); + self.buf.push_type_hole(&name); } else { // write type id self.buf.extend(&ty.0.oid().to_be_bytes());