Skip to content

Commit

Permalink
feat implement Encode,Type for Rc
Browse files Browse the repository at this point in the history
  • Loading branch information
joeydewaal committed Jan 9, 2025
1 parent 3a73ece commit 676e11e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
29 changes: 29 additions & 0 deletions sqlx-core/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::borrow::Cow;
use std::mem;
use std::rc::Rc;
use std::sync::Arc;

use crate::database::Database;
Expand Down Expand Up @@ -216,3 +217,31 @@ where
(**self).size_hint()
}
}

impl<'q, T, DB: Database> Encode<'q, DB> for Rc<T>
where
T: Encode<'q, DB>,
{
#[inline]
fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> Result<IsNull, BoxDynError> {
<T as Encode<DB>>::encode_by_ref(self.as_ref(), buf)
}

#[inline]
fn encode_by_ref(
&self,
buf: &mut <DB as Database>::ArgumentBuffer<'q>,
) -> Result<IsNull, BoxDynError> {
<&T as Encode<DB>>::encode(self, buf)
}

#[inline]
fn produces(&self) -> Option<DB::TypeInfo> {
(**self).produces()
}

#[inline]
fn size_hint(&self) -> usize {
(**self).size_hint()
}
}
12 changes: 11 additions & 1 deletion sqlx-core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! To represent nullable SQL types, `Option<T>` is supported where `T` implements `Type`.
//! An `Option<T>` represents a potentially `NULL` value from SQL.
use std::{borrow::Cow, sync::Arc};
use std::{borrow::Cow, rc::Rc, sync::Arc};

use crate::database::Database;
use crate::type_info::TypeInfo;
Expand Down Expand Up @@ -278,3 +278,13 @@ impl<T: Type<DB>, DB: Database> Type<DB> for Box<T> {
ty.is_null() || <T as Type<DB>>::compatible(ty)
}
}

impl<T: Type<DB>, DB: Database> Type<DB> for Rc<T> {
fn type_info() -> DB::TypeInfo {
<T as Type<DB>>::type_info()
}

fn compatible(ty: &DB::TypeInfo) -> bool {
ty.is_null() || <T as Type<DB>>::compatible(ty)
}
}
20 changes: 17 additions & 3 deletions tests/postgres/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate time_ as time;
use std::borrow::Cow;
use std::net::SocketAddr;
use std::ops::Bound;
use std::rc::Rc;
use std::sync::Arc;

use sqlx::postgres::types::{Oid, PgCiText, PgInterval, PgMoney, PgRange};
Expand Down Expand Up @@ -664,7 +665,7 @@ CREATE TEMPORARY TABLE user_login (
async fn test_arc() -> anyhow::Result<()> {
let mut conn = new::<Postgres>().await?;

let user_age: Arc<i32> = sqlx::query_scalar("select $1 as age ")
let user_age: Arc<i32> = sqlx::query_scalar("SELECT $1 AS age ")
.bind(Arc::new(1i32))
.fetch_one(&mut conn)
.await?;
Expand All @@ -678,7 +679,7 @@ async fn test_cow() -> anyhow::Result<()> {

let age: Cow<'_, i32> = Cow::Owned(1i32);

let user_age: Cow<'static, i32> = sqlx::query_scalar("select $1 as age ")
let user_age: Cow<'static, i32> = sqlx::query_scalar("SELECT $1 AS age ")
.bind(age)
.fetch_one(&mut conn)
.await?;
Expand All @@ -691,11 +692,24 @@ async fn test_cow() -> anyhow::Result<()> {
async fn test_box() -> anyhow::Result<()> {
let mut conn = new::<Postgres>().await?;

let user_age: Box<i32> = sqlx::query_scalar("select $1 as age ")
let user_age: Box<i32> = sqlx::query_scalar("SELECT $1 AS age ")
.bind(Box::new(1))
.fetch_one(&mut conn)
.await?;

assert!(user_age.as_ref() == &1);
Ok(())
}

#[sqlx_macros::test]
async fn test_rc() -> anyhow::Result<()> {
let mut conn = new::<Postgres>().await?;

let user_age: i32 = sqlx::query_scalar("SELECT $1 AS age")
.bind(Rc::new(1i32))
.fetch_one(&mut conn)
.await?;

assert!(user_age == 1);
Ok(())
}

0 comments on commit 676e11e

Please sign in to comment.