use rorm_db::sql::value::NullType;
pub use self::aggregate::*;
pub use self::cmp::*;
use crate::conditions::Value;
use crate::fields::utils::column_name::ColumnName;
use crate::fields::utils::const_fn::ConstFn;
use crate::internal::const_concat::ConstString;
use crate::internal::field::decoder::FieldDecoder;
use crate::internal::hmr::annotations::Annotations;
use crate::{const_fn, sealed};
pub mod aggregate;
pub mod cmp;
pub mod into_value;
pub mod simple;
pub trait FieldType: 'static {
type Columns: Columns;
const NULL: FieldColumns<Self, NullType>;
fn into_values<'a>(self) -> FieldColumns<Self, Value<'a>>;
fn as_values(&self) -> FieldColumns<Self, Value<'_>>;
type Decoder: FieldDecoder<Result = Self>;
type GetNames: ConstFn<(ColumnName,), FieldColumns<Self, ColumnName>>;
type GetAnnotations: ConstFn<(Annotations,), FieldColumns<Self, Annotations>>;
type Check: ConstFn<
(Annotations, FieldColumns<Self, Annotations>),
Result<(), ConstString<1024>>,
>;
}
pub type FieldColumns<F, T> = <<F as FieldType>::Columns as Columns>::Array<T>;
pub trait Columns {
sealed!(trait);
type Array<T>: IntoIterator<Item = T>;
fn map<T, U>(array: Self::Array<T>, f: impl FnMut(T) -> U) -> Self::Array<U>;
const NUM: usize;
type SetNull: ConstFn<(Self::Array<Annotations>,), Self::Array<Annotations>>;
}
pub struct Array<const N: usize>;
impl<const N: usize> Columns for Array<N> {
sealed!(impl);
type Array<T> = [T; N];
fn map<T, U>(array: Self::Array<T>, f: impl FnMut(T) -> U) -> Self::Array<U> {
array.map(f)
}
const NUM: usize = N;
type SetNull = set_null<N>;
}
const_fn! {
pub fn set_null<const N: usize>(annotations: [Annotations; N]) -> [Annotations; N] {
let mut annotations = annotations;
let mut i = 0;
while i < annotations.len() {
annotations[i].nullable = true;
i += 1;
}
annotations
}
}
#[doc(hidden)]
#[allow(non_snake_case)] #[macro_export]
macro_rules! impl_FieldType {
($type:ty, $null_type:ident) => {
impl_FieldType!(
$type,
$null_type,
$crate::fields::utils::check::shared_linter_check<1>
);
};
($type:ty, $null_type:ident, $Check:ty) => {
impl $crate::fields::traits::FieldType for $type {
type Columns = $crate::fields::traits::Array<1>;
const NULL: $crate::fields::traits::FieldColumns<
Self,
$crate::db::sql::value::NullType,
> = [$crate::db::sql::value::NullType::$null_type];
#[inline(always)]
fn as_values(
&self,
) -> $crate::fields::traits::FieldColumns<Self, $crate::conditions::Value<'_>> {
use $crate::fields::traits::into_value::IntoValue;
[self.into_value()]
}
fn into_values<'a>(
self,
) -> $crate::fields::traits::FieldColumns<Self, $crate::conditions::Value<'a>> {
use $crate::fields::traits::into_value::IntoValue;
[self.into_value()]
}
type Decoder = $crate::crud::decoder::DirectDecoder<Self>;
type GetAnnotations = $crate::fields::utils::get_annotations::forward_annotations<1>;
type Check = $Check;
type GetNames = $crate::fields::utils::get_names::single_column_name;
}
};
}