use crate::{db::StatementRow, schema::relation::RelationData, DBResult};
use super::{
Datum, Entity, EntityPart, EntityPartList, EntityPartVisitor, OwnedDatum, OwnedDatumList,
};
macro_rules! build_datum {
($local_id:ident,$stmt:ident,$idx:ident,$d:ident,$t:ident) => {
let $d = <$t::Datum as Datum>::build_from(
RelationData {
local_name: <$t::Entity as Entity>::entity_name(),
part_name: $t::part_name(),
local_id: $local_id,
},
$stmt,
&mut $idx,
)?;
};
}
macro_rules! build_ref_datum {
($local_id:ident,$stmt:ident,$idx:ident,$d:ident,$t:ident) => {
let $d = <<$t::Datum as OwnedDatum>::RefData<'m> as Datum>::build_from(
RelationData {
local_name: <$t::Entity as Entity>::entity_name(),
part_name: $t::part_name(),
local_id: $local_id,
},
$stmt,
&mut $idx,
)?;
};
}
pub struct MarkerPart<E: Entity> {
_ghost: std::marker::PhantomData<E>,
}
impl<E: Entity> Default for MarkerPart<E> {
fn default() -> Self {
Self {
_ghost: Default::default(),
}
}
}
impl<E: Entity> Clone for MarkerPart<E> {
fn clone(&self) -> Self {
Self::default()
}
}
impl<E: Entity> EntityPart for MarkerPart<E> {
type Entity = E;
type Datum = bool;
fn desc() -> Option<&'static str> {
None
}
fn unique() -> bool {
false
}
fn part_name() -> &'static str {
"marker"
}
fn get_datum(_from: &Self::Entity) -> &Self::Datum {
unreachable!()
}
}
#[derive(Debug, Default)]
pub struct EmptyList<E: Entity> {
_ghost: std::marker::PhantomData<E>,
}
impl<E: Entity> EntityPartList for EmptyList<E> {
type Entity = E;
type DatumList = ();
type ListHead = MarkerPart<E>;
type ListTail = EmptyList<E>;
const IS_EMPTY: bool = true;
fn build_datum_list(_stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
Ok(())
}
fn build_datum_ref_list<'l, 'm>(
_stmt: &'l mut StatementRow,
) -> DBResult<<Self::DatumList as OwnedDatumList>::RefList<'m>>
where
'l: 'm,
{
Ok(())
}
fn accept_part_visitor(_: &mut impl EntityPartVisitor) {}
fn accept_part_visitor_ref(
_: &Self::DatumList,
_: &mut impl EntityPartVisitor,
) -> DBResult<()> {
Ok(())
}
}
impl<E: Entity, P0: EntityPart<Entity = E>> EntityPartList for P0 {
type Entity = E;
type DatumList = P0::Datum;
type ListHead = P0;
type ListTail = EmptyList<E>;
fn build_datum_list(stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
let local_id: i64 = stmt.read(0)?;
let mut idx = 1; build_datum!(local_id, stmt, idx, d0, P0);
Ok(d0)
}
fn build_datum_ref_list<'l, 'm>(
stmt: &'l mut StatementRow,
) -> DBResult<<Self::DatumList as OwnedDatumList>::RefList<'m>>
where
'l: 'm,
{
let local_id: i64 = stmt.read(0)?;
let mut idx = 1; build_ref_datum!(local_id, stmt, idx, d0, P0);
Ok(d0)
}
fn accept_part_visitor(v: &mut impl EntityPartVisitor<Entity = Self::Entity>) {
v.visit::<P0>();
}
fn accept_part_visitor_ref(
datum_list: &Self::DatumList,
v: &mut impl EntityPartVisitor<Entity = Self::Entity>,
) -> DBResult<()> {
v.visit_datum::<P0>(datum_list)
}
}
impl<E: Entity, P0: EntityPart<Entity = E>> EntityPartList for (P0,) {
type Entity = E;
type DatumList = (P0::Datum,);
type ListHead = P0;
type ListTail = EmptyList<E>;
fn build_datum_list(stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
let local_id: i64 = stmt.read(0)?;
let mut idx = 1; build_datum!(local_id, stmt, idx, d0, P0);
Ok((d0,))
}
fn build_datum_ref_list<'l, 'm>(
stmt: &'l mut StatementRow,
) -> DBResult<<Self::DatumList as OwnedDatumList>::RefList<'m>>
where
'l: 'm,
{
let local_id: i64 = stmt.read(0)?;
let mut idx = 1; build_ref_datum!(local_id, stmt, idx, d0, P0);
Ok((d0,))
}
fn accept_part_visitor(v: &mut impl EntityPartVisitor<Entity = Self::Entity>) {
v.visit::<P0>();
}
fn accept_part_visitor_ref(
datum_list: &Self::DatumList,
v: &mut impl EntityPartVisitor<Entity = Self::Entity>,
) -> DBResult<()> {
v.visit_datum::<P0>(&datum_list.0)
}
}
macro_rules! part_list_impl {
($p0:ident : $d0:ident : $n0:tt, $($p:ident : $d:ident : $n:tt),+) => {
impl<E: Entity, $p0 : EntityPart<Entity = E>, $( $p : EntityPart<Entity = E> ),* > EntityPartList for ( $p0, $($p),* ) where ( $( $p ),* ,) : EntityPartList<Entity = E, DatumList = ( $( $p ::Datum ),* ,)> {
type Entity = E;
type DatumList = ( $p0 :: Datum, $( $p :: Datum ),* );
type ListHead = $p0;
type ListTail = ( $( $p ),* , );
fn build_datum_list(stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
let local_id: i64 = stmt.read(0)?;
let mut idx = 1;
build_datum!(local_id, stmt, idx, $d0, $p0);
$(
build_datum!(local_id, stmt, idx, $d, $p);
)*
Ok(( $d0, $( $d ),* ))
}
fn build_datum_ref_list<'l, 'm>(stmt: &'l mut StatementRow) -> DBResult<<Self::DatumList as OwnedDatumList>::RefList<'m>> where 'l: 'm {
let local_id: i64 = stmt.read(0)?;
let mut idx = 1;
build_ref_datum!(local_id, stmt, idx, $d0, $p0);
$(
build_ref_datum!(local_id, stmt, idx, $d, $p);
)*
Ok(( $d0, $( $d ),* ))
}
fn accept_part_visitor(v: &mut impl EntityPartVisitor<Entity = Self::Entity>) {
v.visit::< $p0 >();
$(
v.visit::< $p >();
)*
}
fn accept_part_visitor_ref(datum_list: &Self::DatumList, v: &mut impl EntityPartVisitor<Entity = Self::Entity>) -> DBResult<()> {
v.visit_datum::< $p0 >(&datum_list . $n0)?;
$(
v.visit_datum::< $p >(&datum_list . $n)?;
)*
Ok(())
}
}
}
}
part_list_impl!(P0:d0:0, P1:d1:1);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9, P10:d10:10);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9, P10:d10:10, P11:d11:11);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9, P10:d10:10, P11:d11:11, P12:d12:12);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9, P10:d10:10, P11:d11:11, P12:d12:12, P13:d13:13);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9, P10:d10:10, P11:d11:11, P12:d12:12, P13:d13:13, P14:d14:14);
part_list_impl!(P0:d0:0, P1:d1:1, P2:d2:2, P3:d3:3, P4:d4:4, P5:d5:5, P6:d6:6, P7:d7:7, P8:d8:8, P9:d9:9, P10:d10:10, P11:d11:11, P12:d12:12, P13:d13:13, P14:d14:14, P15:d15:15);