Skip to content

Commit

Permalink
feat: support NonZero* scalar types (#3244)
Browse files Browse the repository at this point in the history
* feat: support `NonZero*` scalar types

This commits adds `Type`, `Encode`, and `Decode` impls for all the
`NonZero*` types from the standard library. They are implemented as
direct proxies to their primitive counterparts, except that when
decoding, the values are checked to not be zero.

* fixup!: remove `non-zero` cargo feature

* fixup!: make `non-zero` module private

* fixup!: rebase and fix trait impls
  • Loading branch information
AlphaKeks authored Jun 5, 2024
1 parent 1ce0e76 commit 6561830
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 5 deletions.
9 changes: 4 additions & 5 deletions sqlx-core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
//!
//! To represent nullable SQL types, `Option<T>` is supported where `T` implements `Type`.
//! An `Option<T>` represents a potentially `NULL` value from SQL.
//!

use crate::{database::Database, type_info::TypeInfo};
use crate::database::Database;
use crate::type_info::TypeInfo;

mod non_zero;

#[cfg(feature = "bstr")]
#[cfg_attr(docsrs, doc(cfg(feature = "bstr")))]
Expand Down Expand Up @@ -60,7 +62,6 @@ pub mod time {
#[cfg_attr(docsrs, doc(cfg(feature = "bigdecimal")))]
#[doc(no_inline)]
pub use bigdecimal::BigDecimal;

#[cfg(feature = "rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "rust_decimal")))]
#[doc(no_inline)]
Expand All @@ -82,7 +83,6 @@ pub mod mac_address {

#[cfg(feature = "json")]
pub use json::{Json, JsonRawValue, JsonValue};

pub use text::Text;

/// Indicates that a SQL type is supported for a database.
Expand Down Expand Up @@ -193,7 +193,6 @@ pub use text::Text;
/// price: f64
/// }
/// ```
///
pub trait Type<DB: Database> {
/// Returns the canonical SQL type for this Rust type.
///
Expand Down
76 changes: 76 additions & 0 deletions sqlx-core/src/types/non_zero.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//! [`Type`], [`Encode`], and [`Decode`] implementations for the various [`NonZero*`][non-zero]
//! types from the standard library.
//!
//! [non-zero]: core::num::NonZero

use std::num::{
NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8,
};

use crate::database::Database;
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::types::Type;

macro_rules! impl_non_zero {
($($int:ty => $non_zero:ty),* $(,)?) => {
$(impl<DB> Type<DB> for $non_zero
where
DB: Database,
$int: Type<DB>,
{
fn type_info() -> <DB as Database>::TypeInfo {
<$int as Type<DB>>::type_info()
}

fn compatible(ty: &<DB as Database>::TypeInfo) -> bool {
<$int as Type<DB>>::compatible(ty)
}
}

impl<'q, DB> Encode<'q, DB> for $non_zero
where
DB: Database,
$int: Encode<'q, DB>,
{
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> Result<IsNull, crate::error::BoxDynError> {
<$int as Encode<'q, DB>>::encode_by_ref(&self.get(), buf)
}

fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> Result<IsNull, crate::error::BoxDynError>
where
Self: Sized,
{
<$int as Encode<'q, DB>>::encode(self.get(), buf)
}

fn produces(&self) -> Option<<DB as Database>::TypeInfo> {
<$int as Encode<'q, DB>>::produces(&self.get())
}
}

impl<'r, DB> Decode<'r, DB> for $non_zero
where
DB: Database,
$int: Decode<'r, DB>,
{
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, crate::error::BoxDynError> {
let int = <$int as Decode<'r, DB>>::decode(value)?;
let non_zero = Self::try_from(int)?;

Ok(non_zero)
}
})*
};
}

impl_non_zero! {
i8 => NonZeroI8,
u8 => NonZeroU8,
i16 => NonZeroI16,
u16 => NonZeroU16,
i32 => NonZeroI32,
u32 => NonZeroU32,
i64 => NonZeroI64,
u64 => NonZeroU64,
}

0 comments on commit 6561830

Please sign in to comment.