|
@@ -21,9 +21,60 @@ macro_rules! build_datum {
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
-impl EntityPartList for () {
|
|
|
|
|
|
+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 = usize;
|
|
|
|
+
|
|
|
|
+ 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!()
|
|
|
|
+ }
|
|
|
|
+ fn placeholder() -> &'static str {
|
|
|
|
+ "MarkerPart"
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/// Empty list of entity parts. Since [`EntityPartList`] requires an associated [`Entity`], a
|
|
|
|
+/// simple unit type is insufficient.
|
|
|
|
+#[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 DatumList = ();
|
|
|
|
|
|
|
|
+ type ListHead = MarkerPart<E>;
|
|
|
|
+ type ListTail = EmptyList<E>;
|
|
|
|
+ const IS_EMPTY: bool = true;
|
|
|
|
+
|
|
fn build_datum_list(_conn: &Connection, _stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
fn build_datum_list(_conn: &Connection, _stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
@@ -32,9 +83,13 @@ impl EntityPartList for () {
|
|
fn accept_part_visitor_ref(_: &Self::DatumList, _: &mut impl EntityPartVisitor) {}
|
|
fn accept_part_visitor_ref(_: &Self::DatumList, _: &mut impl EntityPartVisitor) {}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<P0: EntityPart> EntityPartList for P0 {
|
|
|
|
|
|
+impl<E: Entity, P0: EntityPart<Entity = E>> EntityPartList for P0 {
|
|
|
|
+ type Entity = E;
|
|
type DatumList = P0::Datum;
|
|
type DatumList = P0::Datum;
|
|
|
|
|
|
|
|
+ type ListHead = P0;
|
|
|
|
+ type ListTail = EmptyList<E>;
|
|
|
|
+
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
let local_id: i64 = stmt.read(0)?;
|
|
let local_id: i64 = stmt.read(0)?;
|
|
let mut idx = 1; // starting index is 1 since index 0 is the ID
|
|
let mut idx = 1; // starting index is 1 since index 0 is the ID
|
|
@@ -51,9 +106,13 @@ impl<P0: EntityPart> EntityPartList for P0 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<P0: EntityPart> EntityPartList for (P0,) {
|
|
|
|
|
|
+impl<E: Entity, P0: EntityPart<Entity = E>> EntityPartList for (P0,) {
|
|
|
|
+ type Entity = E;
|
|
type DatumList = P0::Datum;
|
|
type DatumList = P0::Datum;
|
|
|
|
|
|
|
|
+ type ListHead = P0;
|
|
|
|
+ type ListTail = EmptyList<E>;
|
|
|
|
+
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
<P0 as EntityPartList>::build_datum_list(conn, stmt)
|
|
<P0 as EntityPartList>::build_datum_list(conn, stmt)
|
|
}
|
|
}
|
|
@@ -67,27 +126,34 @@ impl<P0: EntityPart> EntityPartList for (P0,) {
|
|
}
|
|
}
|
|
|
|
|
|
macro_rules! part_list_impl {
|
|
macro_rules! part_list_impl {
|
|
- ($($p:ident : $d:ident : $n:tt),+) => {
|
|
|
|
- impl< $( $p : EntityPart ),* > EntityPartList for ( $($p),* ) {
|
|
|
|
- type DatumList = ( $( $p :: Datum ),* );
|
|
|
|
|
|
+ ($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),* ) {
|
|
|
|
+ type Entity = E;
|
|
|
|
+ type DatumList = ( $p0 :: Datum, $( $p :: Datum ),* );
|
|
|
|
+
|
|
|
|
+ type ListHead = $p0;
|
|
|
|
+ type ListTail = ( $( $p ),* , );
|
|
|
|
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList> {
|
|
let local_id: i64 = stmt.read(0)?;
|
|
let local_id: i64 = stmt.read(0)?;
|
|
let mut idx = 1;
|
|
let mut idx = 1;
|
|
|
|
+ build_datum!(conn, local_id, stmt, idx, $d0, $p0);
|
|
$(
|
|
$(
|
|
build_datum!(conn, local_id, stmt, idx, $d, $p);
|
|
build_datum!(conn, local_id, stmt, idx, $d, $p);
|
|
)*
|
|
)*
|
|
|
|
|
|
- Ok(( $( $d ),* ))
|
|
|
|
|
|
+ Ok(( $d0, $( $d ),* ))
|
|
}
|
|
}
|
|
|
|
|
|
fn accept_part_visitor(v: &mut impl EntityPartVisitor) {
|
|
fn accept_part_visitor(v: &mut impl EntityPartVisitor) {
|
|
|
|
+ v.visit::< $p0 >();
|
|
$(
|
|
$(
|
|
v.visit::< $p >();
|
|
v.visit::< $p >();
|
|
)*
|
|
)*
|
|
}
|
|
}
|
|
|
|
|
|
fn accept_part_visitor_ref(datum_list: &Self::DatumList, v: &mut impl EntityPartVisitor) {
|
|
fn accept_part_visitor_ref(datum_list: &Self::DatumList, v: &mut impl EntityPartVisitor) {
|
|
|
|
+ v.visit_datum::< $p0 >(&datum_list . $n0);
|
|
$(
|
|
$(
|
|
v.visit_datum::< $p >(&datum_list . $n);
|
|
v.visit_datum::< $p >(&datum_list . $n);
|
|
)*
|
|
)*
|