Skip to content

Commit

Permalink
Implemented FieldEq and FieldOrd for chrono and options
Browse files Browse the repository at this point in the history
  • Loading branch information
gammelalf committed Sep 5, 2023
1 parent 5b6d607 commit caa3c3f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 29 deletions.
76 changes: 49 additions & 27 deletions src/fields/traits/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

use std::borrow::Cow;

use rorm_db::sql::value::NullType;

use super::FieldType;
use crate::conditions::{Binary, BinaryOperator, Column, Condition, Value};
use crate::internal::field::access::FieldAccess;
Expand Down Expand Up @@ -142,16 +144,36 @@ impl_FieldEq!(impl<'rhs> FieldEq<'rhs, i32> for i32 { Value::I32 });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, i64> for i64 { Value::I64 });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, f32> for f32 { Value::F32 });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, f64> for f64 { Value::F64 });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<bool>> for Option<bool> { |option: Self| option.map(Value::Bool).unwrap_or(Value::Null(NullType::Bool)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<i16>> for Option<i16> { |option: Self| option.map(Value::I16).unwrap_or(Value::Null(NullType::I16)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<i32>> for Option<i32> { |option: Self| option.map(Value::I32).unwrap_or(Value::Null(NullType::I32)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<i64>> for Option<i64> { |option: Self| option.map(Value::I64).unwrap_or(Value::Null(NullType::I64)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<f32>> for Option<f32> { |option: Self| option.map(Value::F32).unwrap_or(Value::Null(NullType::F32)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<f64>> for Option<f64> { |option: Self| option.map(Value::F64).unwrap_or(Value::Null(NullType::F64)) });

impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs str> for String { conv_string });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs String> for String { conv_string });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, String> for String { conv_string });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Cow<'rhs, str>> for String { conv_string });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<&'rhs str>> for Option<String> { |option: Option<_>| option.map(conv_string).unwrap_or(Value::Null(NullType::String)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<&'rhs String>> for Option<String> { |option: Option<_>| option.map(conv_string).unwrap_or(Value::Null(NullType::String)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<String>> for Option<String> { |option: Option<_>| option.map(conv_string).unwrap_or(Value::Null(NullType::String)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<Cow<'rhs, str>>> for Option<String> { |option: Option<_>| option.map(conv_string).unwrap_or(Value::Null(NullType::String)) });
fn conv_string<'a>(value: impl Into<Cow<'a, str>>) -> Value<'a> {
Value::String(value.into())
}

impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs str> for String { |s| Value::String(Cow::Borrowed(s)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs String> for String { |s| Value::String(Cow::Borrowed(s)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, String> for String { |s| Value::String(Cow::Owned(s)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Cow<'rhs, str>> for String { Value::String });

impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs [u8]> for Vec<u8> { |b| Value::Binary(Cow::Borrowed(b)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs Vec<u8>> for Vec<u8> { |b| Value::Binary(Cow::Borrowed(b)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Vec<u8>> for Vec<u8> { |b| Value::Binary(Cow::Owned(b)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Cow<'rhs, [u8]>> for Vec<u8> { Value::Binary });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs [u8]> for Vec<u8> { conv_bytes });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs Vec<u8>> for Vec<u8> { conv_bytes });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Vec<u8>> for Vec<u8> { conv_bytes });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Cow<'rhs, [u8]>> for Vec<u8> { conv_bytes });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<&'rhs [u8]>> for Option<Vec<u8>> { |option: Option<_>| option.map(conv_bytes).unwrap_or(Value::Null(NullType::Binary)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<&'rhs Vec<u8>>> for Option<Vec<u8>> { |option: Option<_>| option.map(conv_bytes).unwrap_or(Value::Null(NullType::Binary)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<Vec<u8>>> for Option<Vec<u8>> { |option: Option<_>| option.map(conv_bytes).unwrap_or(Value::Null(NullType::Binary)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<Cow<'rhs, [u8]>>> for Option<Vec<u8>> { |option: Option<_>| option.map(conv_bytes).unwrap_or(Value::Null(NullType::Binary)) });
fn conv_bytes<'a>(value: impl Into<Cow<'a, [u8]>>) -> Value<'a> {
Value::Binary(value.into())
}

// Impl FieldEq<FieldProxy> iff FieldEq<Self>
impl<'rhs, F, P, T> FieldEq<'rhs, FieldProxy<F, P>> for T
Expand Down Expand Up @@ -193,41 +215,41 @@ where
macro_rules! impl_FieldOrd {
($lhs:ty, $rhs:ty, $into_value:expr) => {
impl<'rhs> $crate::fields::traits::cmp::FieldOrd<'rhs, $rhs> for $lhs {
type LtCond<A: $crate::FieldAccess> = Binary<Column<A>, Value<'rhs>>;
type LtCond<A: $crate::FieldAccess> = $crate::conditions::Binary<$crate::conditions::Column<A>, $crate::conditions::Value<'rhs>>;
fn field_less_than<A: $crate::FieldAccess>(access: A, value: $rhs) -> Self::LtCond<A> {
Binary {
operator: BinaryOperator::Less,
fst_arg: Column(access),
$crate::conditions::Binary {
operator: $crate::conditions::BinaryOperator::Less,
fst_arg: $crate::conditions::Column(access),
#[allow(clippy::redundant_closure_call)] // clean way to pass code to a macro
snd_arg: $into_value(value),
}
}

type LeCond<A: $crate::FieldAccess> = Binary<Column<A>, Value<'rhs>>;
type LeCond<A: $crate::FieldAccess> = $crate::conditions::Binary<$crate::conditions::Column<A>, $crate::conditions::Value<'rhs>>;
fn field_less_equals<A: $crate::FieldAccess>(access: A, value: $rhs) -> Self::LeCond<A> {
Binary {
operator: BinaryOperator::LessOrEquals,
fst_arg: Column(access),
$crate::conditions::Binary {
operator: $crate::conditions::BinaryOperator::LessOrEquals,
fst_arg: $crate::conditions::Column(access),
#[allow(clippy::redundant_closure_call)] // clean way to pass code to a macro
snd_arg: $into_value(value),
}
}

type GtCond<A: FieldAccess> = Binary<Column<A>, Value<'rhs>>;
fn field_greater_than<A: FieldAccess>(access: A, value: $rhs) -> Self::GtCond<A> {
Binary {
operator: BinaryOperator::Greater,
fst_arg: Column(access),
type GtCond<A: $crate::FieldAccess> = $crate::conditions::Binary<$crate::conditions::Column<A>, $crate::conditions::Value<'rhs>>;
fn field_greater_than<A: $crate::FieldAccess>(access: A, value: $rhs) -> Self::GtCond<A> {
$crate::conditions::Binary {
operator: $crate::conditions::BinaryOperator::Greater,
fst_arg: $crate::conditions::Column(access),
#[allow(clippy::redundant_closure_call)] // clean way to pass code to a macro
snd_arg: $into_value(value),
}
}

type GeCond<A: FieldAccess> = Binary<Column<A>, Value<'rhs>>;
fn field_greater_equals<A: FieldAccess>(access: A, value: $rhs) -> Self::GeCond<A> {
Binary {
operator: BinaryOperator::GreaterOrEquals,
fst_arg: Column(access),
type GeCond<A: $crate::FieldAccess> = $crate::conditions::Binary<$crate::conditions::Column<A>, $crate::conditions::Value<'rhs>>;
fn field_greater_equals<A: $crate::FieldAccess>(access: A, value: $rhs) -> Self::GeCond<A> {
$crate::conditions::Binary {
operator: $crate::conditions::BinaryOperator::GreaterOrEquals,
fst_arg: $crate::conditions::Column(access),
#[allow(clippy::redundant_closure_call)] // clean way to pass code to a macro
snd_arg: $into_value(value),
}
Expand Down
25 changes: 24 additions & 1 deletion src/fields/types/chrono.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::marker::PhantomData;

use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
use rorm_db::sql::value::NullType;
use rorm_db::Error::DecodeError;
use rorm_db::{Error, Row};
use rorm_declaration::imr;
Expand All @@ -16,12 +17,34 @@ use crate::internal::hmr::{db_type, Source};
use crate::internal::query_context::QueryContext;
use crate::internal::relation_path::Path;
use crate::model::ConstNew;
use crate::{const_concat, impl_AsDbType, new_converting_decoder, sealed};
use crate::{
const_concat, impl_AsDbType, impl_FieldEq, impl_FieldOrd, new_converting_decoder, sealed,
};

impl_AsDbType!(NaiveTime, db_type::Time, Value::ChronoNaiveTime);
impl_AsDbType!(NaiveDate, db_type::Date, Value::ChronoNaiveDate);
impl_AsDbType!(NaiveDateTime, db_type::DateTime, Value::ChronoNaiveDateTime);
impl_AsDbType!(DateTime<Utc>, db_type::DateTime, Value::ChronoDateTime);
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, NaiveTime> for NaiveTime { Value::ChronoNaiveTime });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, NaiveDate> for NaiveDate { Value::ChronoNaiveDate });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, NaiveDateTime> for NaiveDateTime { Value::ChronoNaiveDateTime });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, DateTime<Utc>> for DateTime<Utc> { Value::ChronoDateTime });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<NaiveTime>> for Option<NaiveTime> { |option: Self| option.map(Value::ChronoNaiveTime).unwrap_or(Value::Null(NullType::ChronoNaiveTime)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<NaiveDate>> for Option<NaiveDate> { |option: Self| option.map(Value::ChronoNaiveDate).unwrap_or(Value::Null(NullType::ChronoNaiveDate)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<NaiveDateTime>> for Option<NaiveDateTime> { |option: Self| option.map(Value::ChronoNaiveDateTime).unwrap_or(Value::Null(NullType::ChronoNaiveDateTime)) });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<DateTime<Utc>>> for Option<DateTime<Utc>> { |option: Self| option.map(Value::ChronoDateTime).unwrap_or(Value::Null(NullType::ChronoDateTime)) });
impl_FieldOrd!(NaiveTime, NaiveTime, Value::ChronoNaiveTime);
impl_FieldOrd!(NaiveDate, NaiveDate, Value::ChronoNaiveDate);
impl_FieldOrd!(NaiveDateTime, NaiveDateTime, Value::ChronoNaiveDateTime);
impl_FieldOrd!(DateTime<Utc>, DateTime<Utc>, Value::ChronoDateTime);
#[rustfmt::skip]
impl_FieldOrd!(Option<NaiveTime>, Option<NaiveTime>, |option: Self| option.map(Value::ChronoNaiveTime).unwrap_or(Value::Null(NullType::ChronoNaiveTime)));
#[rustfmt::skip]
impl_FieldOrd!(Option<NaiveDate>, Option<NaiveDate>, |option: Self| option.map(Value::ChronoNaiveDate).unwrap_or(Value::Null(NullType::ChronoNaiveDate)));
#[rustfmt::skip]
impl_FieldOrd!(Option<NaiveDateTime>, Option<NaiveDateTime>, |option: Self| option.map(Value::ChronoNaiveDateTime).unwrap_or(Value::Null(NullType::ChronoNaiveDateTime)));
#[rustfmt::skip]
impl_FieldOrd!(Option<DateTime<Utc>>, Option<DateTime<Utc>>, |option: Self| option.map(Value::ChronoDateTime).unwrap_or(Value::Null(NullType::ChronoDateTime)));

/// Implementation detail of [`DateTime<FixedOffset>`]
const _: () = {
Expand Down
6 changes: 5 additions & 1 deletion src/fields/types/uuid.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use rorm_db::sql::value::NullType;
use uuid::Uuid;

use crate::conditions::Value;
use crate::internal::hmr::db_type;
use crate::{impl_AsDbType, impl_FieldEq};

impl_AsDbType!(uuid::Uuid, db_type::Binary, Value::Uuid);
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, uuid::Uuid> for uuid::Uuid { Value::Uuid });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Uuid> for Uuid { Value::Uuid });
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Option<Uuid>> for Option<Uuid> { |option: Option<_>| option.map(Value::Uuid).unwrap_or(Value::Null(NullType::Uuid)) });

0 comments on commit caa3c3f

Please sign in to comment.