|
@@ -36,7 +36,7 @@ pub trait EntityPart: Default + Clone + 'static {
|
|
|
|
|
|
/// String representing the field name.
|
|
|
fn part_name() -> &'static str;
|
|
|
- /// Whether this field has a #[unique] attribute or not.
|
|
|
+ /// Whether this field has a `#[unique]` attribute or not.
|
|
|
fn unique() -> bool;
|
|
|
/// Documentation comment for this field.
|
|
|
fn desc() -> Option<&'static str>;
|
|
@@ -47,24 +47,40 @@ pub trait EntityPart: Default + Clone + 'static {
|
|
|
|
|
|
/// Visitor for traversing all [`EntityPart`]s in an [`Entity`] or [`EntityPartList`].
|
|
|
pub trait EntityPartVisitor {
|
|
|
+ /// The [`Entity`] that this visitor will traverse over the parts of.
|
|
|
type Entity: Entity;
|
|
|
+ /// Visit a part, with no instance information.
|
|
|
fn visit<EP: EntityPart<Entity = Self::Entity>>(&mut self) {}
|
|
|
+ /// Visit a part, with a datum reference.
|
|
|
fn visit_datum<EP: EntityPart<Entity = Self::Entity>>(&mut self, _datum: &EP::Datum) {}
|
|
|
+ /// Visit a part, with a mutable datum reference.
|
|
|
fn visit_datum_mut<EP: EntityPart<Entity = Self::Entity>>(&mut self, _datum: &mut EP::Datum) {}
|
|
|
}
|
|
|
|
|
|
/// List of EntityParts.
|
|
|
pub trait EntityPartList: 'static {
|
|
|
+ /// The [`Entity`] that this list represents the parts of.
|
|
|
type Entity: Entity;
|
|
|
+ /// A [`ConcreteDatumList`] type that matches this part list, formed as the `EntityPart::Datum`s of
|
|
|
+ /// each `EntityPart` in this list.
|
|
|
type DatumList: ConcreteDatumList + QueryEquivalentList<Self::DatumList>;
|
|
|
|
|
|
- type ListHead: EntityPart;
|
|
|
+ /// The first element of this list. If this list is empty, this will be a generic marker type
|
|
|
+ /// with poisoned values to be easily visible if processed.
|
|
|
+ type ListHead: EntityPart<Entity = Self::Entity>;
|
|
|
+ /// An [`EntityPartList`] that represents all but the first element of this list.
|
|
|
type ListTail: EntityPartList<Entity = Self::Entity>;
|
|
|
+ /// Whether the current list is empty. Should be used to control recursion if iterating across
|
|
|
+ /// the list.
|
|
|
const IS_EMPTY: bool = false;
|
|
|
|
|
|
+ /// Construct an instance of `Self::DatumList` from a table row.
|
|
|
fn build_datum_list(conn: &Connection, stmt: &mut StatementRow) -> DBResult<Self::DatumList>;
|
|
|
|
|
|
+ /// Accept a visitor to iterate across each part in the list, with no datum instances.
|
|
|
fn accept_part_visitor(_: &mut impl EntityPartVisitor<Entity = Self::Entity>);
|
|
|
+ /// Accept a visitor to iterate across each part in the list, with datum instances provided by
|
|
|
+ /// a `Self::DatumList` instance.
|
|
|
fn accept_part_visitor_ref(
|
|
|
datum_list: &Self::DatumList,
|
|
|
_: &mut impl EntityPartVisitor<Entity = Self::Entity>,
|
|
@@ -74,6 +90,7 @@ pub trait EntityPartList: 'static {
|
|
|
// trait implementations for EntityPartList
|
|
|
mod part_list;
|
|
|
|
|
|
+/// A sentinel type representing a zero-length [`EntityPartList`].
|
|
|
pub use part_list::EmptyList;
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
@@ -82,19 +99,32 @@ pub use part_list::EmptyList;
|
|
|
|
|
|
/// A single database entity, aka an object type that gets its own table.
|
|
|
pub trait Entity: 'static + std::fmt::Debug {
|
|
|
+ /// A list of all the [`EntityPart`]s that make up the fields of the struct.
|
|
|
type Parts: EntityPartList<Entity = Self>;
|
|
|
+ /// A list of the [`EntityPart`]s that make up the list of access keys for the entity. Can be an
|
|
|
+ /// [`EmptyList`] if no keys are defined.
|
|
|
type Keys: EntityPartList<Entity = Self>;
|
|
|
+ /// The corresponding [`EntityID`] type for this Entity.
|
|
|
type ID: EntityID<Entity = Self> + EntityPart<Datum = Self::ID, Entity = Self>;
|
|
|
|
|
|
+ /// Construct an instance of this entity from a list of datums that matches each part, in
|
|
|
+ /// order.
|
|
|
fn build(values: <Self::Parts as EntityPartList>::DatumList) -> Self;
|
|
|
|
|
|
+ /// A static string used as the database table name for the entity.
|
|
|
fn entity_name() -> &'static str;
|
|
|
+ /// Accept a visitor to iterate across each part in the entity, with no datum instances.
|
|
|
fn accept_part_visitor(visitor: &mut impl EntityPartVisitor<Entity = Self>);
|
|
|
+ /// Accept a visitor to iterate across each part in the entity, with datum instances pulled
|
|
|
+ /// from an instance of `Self`.
|
|
|
fn accept_part_visitor_ref(&self, visitor: &mut impl EntityPartVisitor<Entity = Self>);
|
|
|
+ /// Accept a visitor to iterate across each part in the entity, with mutable datum instances
|
|
|
+ /// pulled from an instance of `Self`.
|
|
|
fn accept_part_visitor_mut(&mut self, _: &mut impl EntityPartVisitor<Entity = Self>);
|
|
|
}
|
|
|
|
|
|
/// Visitor for traversing all [`Entity`]s in a container type.
|
|
|
pub trait EntityVisitor {
|
|
|
+ /// Visit a particular entity.
|
|
|
fn visit<E: Entity>(&mut self);
|
|
|
}
|