use std::marker::PhantomData;
use rorm_db::row::DecodeOwned;
use crate::crud::decoder::{Decoder, DirectDecoder, NoopDecoder};
use crate::fields::proxy::FieldProxyImpl;
use crate::internal::field::{Field, FieldProxy};
use crate::internal::query_context::QueryContext;
pub trait FieldDecoder: Decoder {
fn new<I>(ctx: &mut QueryContext, _: FieldProxy<I>) -> Self
where
I: FieldProxyImpl<Field: Field<Type = Self::Result>>;
}
impl<T> FieldDecoder for DirectDecoder<T>
where
T: DecodeOwned,
{
fn new<I>(ctx: &mut QueryContext, _: FieldProxy<I>) -> Self
where
I: FieldProxyImpl<Field: Field<Type = Self::Result>>,
{
let (index, column) = ctx.select_field::<I::Field, I::Path>();
Self {
result: PhantomData,
column,
index,
}
}
}
impl<T> FieldDecoder for NoopDecoder<T>
where
T: Default,
{
fn new<I>(_: &mut QueryContext, _: FieldProxy<I>) -> Self
where
I: FieldProxyImpl<Field: Field<Type = Self::Result>>,
{
Self(PhantomData)
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! new_converting_decoder {
($(#[$attr:meta])* $vis:vis $decoder:ident$(<$($generic:ident$(: $bound1:ident $(+ $boundN:ident)*)?),+>)?, |$convert_arg:ident: $primitive:ty| -> $result:ty $convert_block:block) => {
$(#[$attr])*
$vis struct $decoder$(<$($generic),+>)? {
column: String,
index: usize,
$(generics: ::std::marker::PhantomData<($($generic,)+)>)?
}
impl$(<$($generic),*>)? $crate::crud::decoder::Decoder for $decoder$(<$($generic),+>)?
where
$($($(
$generic: $bound1,
$($generic: $boundN,)*
)?)+)?
{
type Result = $result;
fn by_name<'index>(&'index self, row: &'_ $crate::Row) -> Result<Self::Result, $crate::db::row::RowError<'index>> {
let $convert_arg: $primitive = row.get(self.column.as_str())?;
let convert_result = $convert_block;
convert_result.map_err(|error| $crate::db::row::RowError::Decode {
index: self.column.as_str().into(),
source: error.into(),
})
}
fn by_index<'index>(&'index self, row: &'_ $crate::Row) -> Result<Self::Result, $crate::db::row::RowError<'index>> {
let $convert_arg: $primitive = row.get(self.index)?;
let convert_result = $convert_block;
convert_result.map_err(|error| $crate::db::row::RowError::Decode {
index: self.index.into(),
source: error.into(),
})
}
}
impl$(<$($generic),*>)? $crate::internal::field::decoder::FieldDecoder for $decoder$(<$($generic),+>)?
where
$($($(
$generic: $bound1,
$($generic: $boundN,)*
)?)+)?
{
fn new<I>(
ctx: &mut $crate::internal::query_context::QueryContext,
_: $crate::fields::proxy::FieldProxy<I>
) -> Self
where
I: $crate::fields::proxy::FieldProxyImpl<
Field: $crate::internal::field::Field<
Type = Self::Result
>,
>,
{
let (index, column) = ctx.select_field::<I::Field, I::Path>();
Self {
column,
index,
$(generics: ::std::marker::PhantomData::<($($generic,)+)>)?
}
}
}
};
}