Skip to content

Commit

Permalink
Replaced array_utils with new approach
Browse files Browse the repository at this point in the history
  • Loading branch information
gammelalf committed Sep 6, 2024
1 parent 18ef1c0 commit 9fd3b67
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 100 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Since 0.6.3
- removed `AsDbType::from_primitive`
- fixed names of join aliases
- changed name generation for join and column aliases
- redesigned associated type `Columns` on trait `FieldType`

Notes for publishing
--------------------
Expand Down
37 changes: 32 additions & 5 deletions src/fields/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Traits defining types which can be used as fields.

use crate::conditions::Value;
use crate::internal::array_utils::Array;
use crate::internal::field::decoder::FieldDecoder;
use crate::internal::field::modifier::{AnnotationsModifier, CheckModifier, ColumnsFromName};
use crate::internal::field::Field;
Expand All @@ -11,19 +10,21 @@ pub mod cmp;

pub use cmp::*;

use crate::sealed;

/// Base trait for types which are allowed as fields in models
pub trait FieldType: 'static {
/// Array with length specific to the field type
type Columns<T>: Array<Item = T>;
type Columns: Columns;

/// Construct an array of [`Value`] representing `self` in the database via ownership
fn into_values(self) -> Self::Columns<Value<'static>>;
fn into_values(self) -> FieldColumns<Self, Value<'static>>;

/// Construct an array of [`Value`] representing `self` in the database via borrowing
fn as_values(&self) -> Self::Columns<Value<'_>>;
fn as_values(&self) -> FieldColumns<Self, Value<'_>>;

/// Construct an array of [`imr::Field`] representing this type
fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field>;
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field>;

/// [`FieldDecoder`] to use for fields of this type
type Decoder: FieldDecoder<Result = Self>;
Expand All @@ -43,3 +44,29 @@ pub trait FieldType: 'static {
/// `const fn<F: Field>() -> Self::Columns<&'static str>`
type ColumnsFromName<F: Field<Type = Self>>: ColumnsFromName<F>;
}
/// Shorthand for constructing an array with the length for the [`FieldType`]'s columns
pub type FieldColumns<F, T> = <<F as FieldType>::Columns as Columns>::Array<T>;

/// The trait for the [`FieldType`]'s `Columns` associated type.
///
/// It is implemented by [`Array`] and is equivalent to a fixed length.
pub trait Columns {
sealed!(trait);

/// Array of length `NUM` to store columns' information in
type Array<T>: IntoIterator<Item = T>;

/// The number of columns
const NUM: usize;
}

/// Implementor of [`Columns`] used to specify the number of a [`FieldType`]'s columns
pub struct Array<const N: usize>;

impl<const N: usize> Columns for Array<N> {
sealed!(impl);

type Array<T> = [T; N];

const NUM: usize = N;
}
10 changes: 5 additions & 5 deletions src/fields/types/back_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rorm_declaration::imr;
use crate::conditions::collections::CollectionOperator::Or;
use crate::conditions::{Binary, BinaryOperator, Column, Condition, DynamicCollection, Value};
use crate::crud::decoder::NoopDecoder;
use crate::fields::traits::FieldType;
use crate::fields::traits::{Array, FieldColumns, FieldType};
use crate::internal::field::foreign_model::{ForeignModelField, ForeignModelTrait};
use crate::internal::field::modifier::{EraseAnnotations, NoCheck, NoColumnFromName};
use crate::internal::field::{foreign_model, Field, FieldProxy, SingleColumnField};
Expand Down Expand Up @@ -41,17 +41,17 @@ impl<FMF: ForeignModelField> BackRef<FMF> {
}

impl<FMF: ForeignModelField> FieldType for BackRef<FMF> {
type Columns<T> = [T; 0];
type Columns = Array<0>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
[]
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
[]
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
[]
}

Expand Down
18 changes: 9 additions & 9 deletions src/fields/types/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::de::DeserializeOwned;
use serde::Serialize;

use crate::conditions::Value;
use crate::fields::traits::FieldType;
use crate::fields::traits::{Array, FieldColumns, FieldType};
use crate::internal::field::as_db_type::{get_single_imr, AsDbType};
use crate::internal::field::modifier::{MergeAnnotations, SingleColumnCheck, SingleColumnFromName};
use crate::internal::field::Field;
Expand Down Expand Up @@ -52,21 +52,21 @@ new_converting_decoder!(
}
);
impl<T: Serialize + DeserializeOwned + 'static> FieldType for Json<T> {
type Columns<C> = [C; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
[Value::Binary(Cow::Owned(
serde_json::to_vec(&self.0).unwrap(),
))] // TODO propagate error?
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
[Value::Binary(Cow::Owned(
serde_json::to_vec(&self.0).unwrap(),
))] // TODO propagate error?
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::Binary)
}

Expand Down Expand Up @@ -96,20 +96,20 @@ new_converting_decoder!(
}
);
impl<T: Serialize + DeserializeOwned + 'static> FieldType for Option<Json<T>> {
type Columns<C> = [C; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
self.map(Json::into_values)
.unwrap_or([Value::Null(Binary::NULL_TYPE)])
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
self.as_ref()
.map(Json::as_values)
.unwrap_or([Value::Null(Binary::NULL_TYPE)])
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::Binary)
}

Expand Down
18 changes: 9 additions & 9 deletions src/fields/types/max_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::conditions::Value;
use crate::crud::decoder::Decoder;
use crate::fields::traits::FieldType;
use crate::fields::traits::{Array, FieldColumns, FieldType};
use crate::fields::types::max_str_impl::{LenImpl, NumBytes};
use crate::impl_FieldEq;
use crate::internal::field::as_db_type::{get_single_imr, AsDbType};
Expand Down Expand Up @@ -182,17 +182,17 @@ impl<const MAX_LEN: usize, Impl> FieldType for MaxStr<MAX_LEN, Impl, String>
where
Impl: LenImpl + Default + 'static,
{
type Columns<T> = [T; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
[Value::String(Cow::Owned(self.string))]
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
[Value::String(Cow::Borrowed(&self.string))]
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::VarChar)
}

Expand Down Expand Up @@ -247,25 +247,25 @@ impl<const MAX_LEN: usize, Impl> FieldType for Option<MaxStr<MAX_LEN, Impl, Stri
where
Impl: LenImpl + Default + 'static,
{
type Columns<T> = [T; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
[if let Some(string) = self {
Value::String(Cow::Owned(string.string))
} else {
Value::Null(NullType::String)
}]
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
[if let Some(string) = self {
Value::String(Cow::Borrowed(&string.string))
} else {
Value::Null(NullType::String)
}]
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::VarChar)
}

Expand Down
18 changes: 9 additions & 9 deletions src/fields/types/msgpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::de::DeserializeOwned;
use serde::Serialize;

use crate::conditions::Value;
use crate::fields::traits::FieldType;
use crate::fields::traits::{Array, FieldColumns, FieldType};
use crate::internal::field::as_db_type::{get_single_imr, AsDbType};
use crate::internal::field::modifier::{MergeAnnotations, SingleColumnCheck, SingleColumnFromName};
use crate::internal::field::Field;
Expand Down Expand Up @@ -52,21 +52,21 @@ new_converting_decoder!(
}
);
impl<T: Serialize + DeserializeOwned + 'static> FieldType for MsgPack<T> {
type Columns<C> = [C; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
[Value::Binary(Cow::Owned(
rmp_serde::to_vec(&self.0).unwrap(), // TODO propagate error?
))]
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
[Value::Binary(Cow::Owned(
rmp_serde::to_vec(&self.0).unwrap(), // TODO propagate error?
))]
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::Binary)
}

Expand Down Expand Up @@ -96,20 +96,20 @@ new_converting_decoder!(
}
);
impl<T: Serialize + DeserializeOwned + 'static> FieldType for Option<MsgPack<T>> {
type Columns<C> = [C; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
self.map(MsgPack::into_values)
.unwrap_or([Value::Null(Binary::NULL_TYPE)])
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
self.as_ref()
.map(MsgPack::as_values)
.unwrap_or([Value::Null(Binary::NULL_TYPE)])
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::Binary)
}

Expand Down
18 changes: 9 additions & 9 deletions src/fields/types/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rorm_declaration::imr;
use url::Url;

use crate::conditions::Value;
use crate::fields::traits::FieldType;
use crate::fields::traits::{Array, FieldColumns, FieldType};
use crate::internal::field::as_db_type::{get_single_imr, AsDbType};
use crate::internal::field::modifier::{MergeAnnotations, SingleColumnCheck, SingleColumnFromName};
use crate::internal::field::Field;
Expand All @@ -15,18 +15,18 @@ impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs Url> for Url {|url: &'rhs Url| Valu
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Url> for Url {|url: Url| Value::String(Cow::Owned(url.into()))});

impl FieldType for Url {
type Columns<T> = [T; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
[Value::String(Cow::Owned(self.into()))]
}

#[inline(always)]
fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
[Value::String(Cow::Borrowed(self.as_str()))]
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::VarChar)
}

Expand All @@ -51,21 +51,21 @@ new_converting_decoder!(
);

impl FieldType for Option<Url> {
type Columns<T> = [T; 1];
type Columns = Array<1>;

fn into_values(self) -> Self::Columns<Value<'static>> {
fn into_values(self) -> FieldColumns<Self, Value<'static>> {
self.map(<Url>::into_values).unwrap_or([Value::Null(
<<Url as AsDbType>::DbType as hmr::db_type::DbType>::NULL_TYPE,
)])
}

fn as_values(&self) -> Self::Columns<Value<'_>> {
fn as_values(&self) -> FieldColumns<Self, Value<'_>> {
self.as_ref().map(<Url>::as_values).unwrap_or([Value::Null(
<<Url as AsDbType>::DbType as hmr::db_type::DbType>::NULL_TYPE,
)])
}

fn get_imr<F: Field<Type = Self>>() -> Self::Columns<imr::Field> {
fn get_imr<F: Field<Type = Self>>() -> FieldColumns<Self, imr::Field> {
get_single_imr::<F>(imr::DbType::VarChar)
}

Expand Down
25 changes: 0 additions & 25 deletions src/internal/array_utils.rs

This file was deleted.

Loading

0 comments on commit 9fd3b67

Please sign in to comment.