From 0bb965e6e943128b4d56cb53e9c0e3e9edbdacfa Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 15 May 2025 15:04:33 +0200 Subject: [PATCH 1/2] Add support for `Box` types. This allows keeping structs that implement FromRow lifetime-free, previously you had to use `&'a JsonRawValue`. ```rust struct Foo { bar: Box, } ``` --- sqlx-core/src/types/json.rs | 24 ++++++++++++++++++++++++ tests/postgres/types.rs | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/sqlx-core/src/types/json.rs b/sqlx-core/src/types/json.rs index fa187f4aab..4d53f292ee 100644 --- a/sqlx-core/src/types/json.rs +++ b/sqlx-core/src/types/json.rs @@ -196,6 +196,20 @@ where } } +impl Type for Box +where + for<'a> Json<&'a Self>: Type, + DB: Database, +{ + fn type_info() -> DB::TypeInfo { + as Type>::type_info() + } + + fn compatible(ty: &DB::TypeInfo) -> bool { + as Type>::compatible(ty) + } +} + // We don't have to implement Encode for JsonRawValue because that's covered by the default // implementation for Encode impl<'r, DB> Decode<'r, DB> for &'r JsonRawValue @@ -207,3 +221,13 @@ where as Decode>::decode(value).map(|item| item.0) } } + +impl<'r, DB> Decode<'r, DB> for Box +where + Json: Decode<'r, DB>, + DB: Database, +{ + fn decode(value: ::ValueRef<'r>) -> Result { + as Decode>::decode(value).map(|item| item.0) + } +} diff --git a/tests/postgres/types.rs b/tests/postgres/types.rs index d5d34bc1b3..0ae0ac5c00 100644 --- a/tests/postgres/types.rs +++ b/tests/postgres/types.rs @@ -465,7 +465,9 @@ mod json { .await?; let value: &JsonRawValue = row.try_get(0)?; + assert_eq!(value.get(), "{\"hello\": \"world\"}"); + let value: Box = row.try_get(0)?; assert_eq!(value.get(), "{\"hello\": \"world\"}"); // prepared, binary API @@ -474,7 +476,9 @@ mod json { .await?; let value: &JsonRawValue = row.try_get(0)?; + assert_eq!(value.get(), "{\"hello\": \"world\"}"); + let value: Box = row.try_get(0)?; assert_eq!(value.get(), "{\"hello\": \"world\"}"); Ok(()) From aab820bc1c62e4e21bec64adaf4557ab04a98953 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 15 May 2025 16:49:37 +0200 Subject: [PATCH 2/2] Add Encode impls for `JsonRawValue`. --- sqlx-core/src/types/json.rs | 41 +++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/sqlx-core/src/types/json.rs b/sqlx-core/src/types/json.rs index 4d53f292ee..f9d95c9b01 100644 --- a/sqlx-core/src/types/json.rs +++ b/sqlx-core/src/types/json.rs @@ -210,8 +210,45 @@ where } } -// We don't have to implement Encode for JsonRawValue because that's covered by the default -// implementation for Encode +impl<'q, DB> Encode<'q, DB> for JsonRawValue +where + for<'a> Json<&'a Self>: Encode<'q, DB>, + DB: Database, +{ + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + as Encode<'q, DB>>::encode(Json(self), buf) + } +} + +impl<'q, DB> Encode<'q, DB> for &'q JsonRawValue +where + for<'a> Json<&'a Self>: Encode<'q, DB>, + DB: Database, +{ + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + as Encode<'q, DB>>::encode(Json(self), buf) + } +} + +impl<'q, DB> Encode<'q, DB> for Box +where + for<'a> Json<&'a Self>: Encode<'q, DB>, + DB: Database, +{ + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + as Encode<'q, DB>>::encode(Json(self), buf) + } +} + impl<'r, DB> Decode<'r, DB> for &'r JsonRawValue where Json: Decode<'r, DB>,