Skip to content

Commit 648250d

Browse files
authored
Add more JsonRawValue encode/decode impls. (#3859)
* Add support for `Box<JsonRawValue>` types. This allows keeping structs that implement FromRow lifetime-free, previously you had to use `&'a JsonRawValue`. ```rust struct Foo { bar: Box<JsonRawValue>, } ``` * Add Encode impls for `JsonRawValue`.
1 parent 99ec419 commit 648250d

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

sqlx-core/src/types/json.rs

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,59 @@ where
196196
}
197197
}
198198

199-
// We don't have to implement Encode for JsonRawValue because that's covered by the default
200-
// implementation for Encode
199+
impl<DB> Type<DB> for Box<JsonRawValue>
200+
where
201+
for<'a> Json<&'a Self>: Type<DB>,
202+
DB: Database,
203+
{
204+
fn type_info() -> DB::TypeInfo {
205+
<Json<&Self> as Type<DB>>::type_info()
206+
}
207+
208+
fn compatible(ty: &DB::TypeInfo) -> bool {
209+
<Json<&Self> as Type<DB>>::compatible(ty)
210+
}
211+
}
212+
213+
impl<'q, DB> Encode<'q, DB> for JsonRawValue
214+
where
215+
for<'a> Json<&'a Self>: Encode<'q, DB>,
216+
DB: Database,
217+
{
218+
fn encode_by_ref(
219+
&self,
220+
buf: &mut <DB as Database>::ArgumentBuffer<'q>,
221+
) -> Result<IsNull, BoxDynError> {
222+
<Json<&Self> as Encode<'q, DB>>::encode(Json(self), buf)
223+
}
224+
}
225+
226+
impl<'q, DB> Encode<'q, DB> for &'q JsonRawValue
227+
where
228+
for<'a> Json<&'a Self>: Encode<'q, DB>,
229+
DB: Database,
230+
{
231+
fn encode_by_ref(
232+
&self,
233+
buf: &mut <DB as Database>::ArgumentBuffer<'q>,
234+
) -> Result<IsNull, BoxDynError> {
235+
<Json<&Self> as Encode<'q, DB>>::encode(Json(self), buf)
236+
}
237+
}
238+
239+
impl<'q, DB> Encode<'q, DB> for Box<JsonRawValue>
240+
where
241+
for<'a> Json<&'a Self>: Encode<'q, DB>,
242+
DB: Database,
243+
{
244+
fn encode_by_ref(
245+
&self,
246+
buf: &mut <DB as Database>::ArgumentBuffer<'q>,
247+
) -> Result<IsNull, BoxDynError> {
248+
<Json<&Self> as Encode<'q, DB>>::encode(Json(self), buf)
249+
}
250+
}
251+
201252
impl<'r, DB> Decode<'r, DB> for &'r JsonRawValue
202253
where
203254
Json<Self>: Decode<'r, DB>,
@@ -207,3 +258,13 @@ where
207258
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
208259
}
209260
}
261+
262+
impl<'r, DB> Decode<'r, DB> for Box<JsonRawValue>
263+
where
264+
Json<Self>: Decode<'r, DB>,
265+
DB: Database,
266+
{
267+
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
268+
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
269+
}
270+
}

tests/postgres/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,9 @@ mod json {
468468
.await?;
469469

470470
let value: &JsonRawValue = row.try_get(0)?;
471+
assert_eq!(value.get(), "{\"hello\": \"world\"}");
471472

473+
let value: Box<JsonRawValue> = row.try_get(0)?;
472474
assert_eq!(value.get(), "{\"hello\": \"world\"}");
473475

474476
// prepared, binary API
@@ -477,7 +479,9 @@ mod json {
477479
.await?;
478480

479481
let value: &JsonRawValue = row.try_get(0)?;
482+
assert_eq!(value.get(), "{\"hello\": \"world\"}");
480483

484+
let value: Box<JsonRawValue> = row.try_get(0)?;
481485
assert_eq!(value.get(), "{\"hello\": \"world\"}");
482486

483487
Ok(())

0 commit comments

Comments
 (0)