|
@@ -15,8 +15,11 @@ mod datum_list;
|
|
|
|
|
|
/// Represents a data field in an Entity.
|
|
/// Represents a data field in an Entity.
|
|
pub trait Datum: Clone + std::fmt::Debug {
|
|
pub trait Datum: Clone + std::fmt::Debug {
|
|
|
|
+ /// The type used in a SQL database to represent this datum.
|
|
fn sql_type() -> &'static str;
|
|
fn sql_type() -> &'static str;
|
|
|
|
|
|
|
|
+ /// Generate a `std::fmt::Debug`-compatible view of the current datum; used to produce more
|
|
|
|
+ /// human-friendly outputs for some more complicated types with state stored in the database.
|
|
fn debug_field(&self, field: &'static str, fmt: &mut std::fmt::DebugStruct)
|
|
fn debug_field(&self, field: &'static str, fmt: &mut std::fmt::DebugStruct)
|
|
where
|
|
where
|
|
Self: Sized,
|
|
Self: Sized,
|
|
@@ -24,16 +27,23 @@ pub trait Datum: Clone + std::fmt::Debug {
|
|
fmt.field(field, self);
|
|
fmt.field(field, self);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// Bind this datum to a [`StatementContext`] at a given index.
|
|
fn bind_to(&self, _stmt: &mut StatementContext, index: i32);
|
|
fn bind_to(&self, _stmt: &mut StatementContext, index: i32);
|
|
|
|
+ /// Construct an instance of this datum from a table row.
|
|
fn build_from(_adata: AssocData, _stmt: &mut StatementRow, _index: &mut i32) -> DBResult<Self>
|
|
fn build_from(_adata: AssocData, _stmt: &mut StatementRow, _index: &mut i32) -> DBResult<Self>
|
|
where
|
|
where
|
|
Self: Sized,
|
|
Self: Sized,
|
|
{
|
|
{
|
|
unreachable!()
|
|
unreachable!()
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /// Update any [`AssocData`] instances.
|
|
|
|
+ #[doc(hidden)]
|
|
fn update_adata(&mut self, _adata: AssocData) {}
|
|
fn update_adata(&mut self, _adata: AssocData) {}
|
|
|
|
|
|
|
|
+ /// Accept an entity visitor to iterate across any entities this Datum type references.
|
|
fn accept_entity_visitor(_: &mut impl EntityVisitor) {}
|
|
fn accept_entity_visitor(_: &mut impl EntityVisitor) {}
|
|
|
|
+ /// Accept a datum discriminator without any instance reference to allow for more fine-grained per-type processing.
|
|
fn accept_discriminator(d: &mut impl DatumDiscriminator)
|
|
fn accept_discriminator(d: &mut impl DatumDiscriminator)
|
|
where
|
|
where
|
|
Self: Sized,
|
|
Self: Sized,
|
|
@@ -41,6 +51,7 @@ pub trait Datum: Clone + std::fmt::Debug {
|
|
d.visit_bare_field::<Self>();
|
|
d.visit_bare_field::<Self>();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// Accept a datum discriminator with an instance reference to allow for more fine-grained per-type processing.
|
|
fn accept_discriminator_ref(&self, d: &mut impl DatumDiscriminatorRef)
|
|
fn accept_discriminator_ref(&self, d: &mut impl DatumDiscriminatorRef)
|
|
where
|
|
where
|
|
Self: Sized,
|
|
Self: Sized,
|
|
@@ -53,41 +64,56 @@ pub trait Datum: Clone + std::fmt::Debug {
|
|
/// to ensure [`QueryEquivalent`] can be implemented in the current Rust type system.
|
|
/// to ensure [`QueryEquivalent`] can be implemented in the current Rust type system.
|
|
pub trait ConcreteDatum: 'static + Datum {}
|
|
pub trait ConcreteDatum: 'static + Datum {}
|
|
|
|
|
|
-/// Visitor for allowing for type-specific behaviour
|
|
|
|
|
|
+/// Visitor for allowing for type-specific behaviour.
|
|
pub trait DatumDiscriminator {
|
|
pub trait DatumDiscriminator {
|
|
|
|
+ /// Visit an `EntityID` type.
|
|
fn visit_entity_id<E: Entity>(&mut self);
|
|
fn visit_entity_id<E: Entity>(&mut self);
|
|
|
|
+ /// Visit a `Serialized<T>` instance.
|
|
fn visit_serialized<T: serde::Serialize + serde::de::DeserializeOwned>(&mut self);
|
|
fn visit_serialized<T: serde::Serialize + serde::de::DeserializeOwned>(&mut self);
|
|
|
|
+ /// Visit a bare datum field instance, such as a `String` or `usize`.
|
|
fn visit_bare_field<T: Datum>(&mut self);
|
|
fn visit_bare_field<T: Datum>(&mut self);
|
|
|
|
+ /// Visit a one-direction association map.
|
|
fn visit_assoc_map<E: Entity>(&mut self);
|
|
fn visit_assoc_map<E: Entity>(&mut self);
|
|
|
|
+ /// Visit the domain side of a bidirectional relation map.
|
|
fn visit_assoc_domain<R: Relation>(&mut self);
|
|
fn visit_assoc_domain<R: Relation>(&mut self);
|
|
|
|
+ /// Visit the range side of a bidirectional relation map.
|
|
fn visit_assoc_range<R: Relation>(&mut self);
|
|
fn visit_assoc_range<R: Relation>(&mut self);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/// Visitor for allowing for type-specific behaviour, with instances passed as references.
|
|
pub trait DatumDiscriminatorRef {
|
|
pub trait DatumDiscriminatorRef {
|
|
|
|
+ /// Visit an `EntityID` instance.
|
|
fn visit_entity_id<E: Entity>(&mut self, _: &E::ID);
|
|
fn visit_entity_id<E: Entity>(&mut self, _: &E::ID);
|
|
|
|
+ /// Visit a `Serialized<T>` instance.
|
|
fn visit_serialized<T: serde::Serialize + serde::de::DeserializeOwned>(&mut self, _: &T);
|
|
fn visit_serialized<T: serde::Serialize + serde::de::DeserializeOwned>(&mut self, _: &T);
|
|
|
|
+ /// Visit a bare datum field instance, such as a `String` or `usize`.
|
|
fn visit_bare_field<T: Datum>(&mut self, _: &T);
|
|
fn visit_bare_field<T: Datum>(&mut self, _: &T);
|
|
|
|
+ /// Visit a one-direction association map instance.
|
|
fn visit_assoc_map<E: Entity>(&mut self, _: &AssocMap<E>);
|
|
fn visit_assoc_map<E: Entity>(&mut self, _: &AssocMap<E>);
|
|
|
|
+ /// Visit an instance of the domain side of a bidirectional relation map.
|
|
fn visit_assoc_domain<R: Relation>(&mut self, _: &AssocDomain<R>);
|
|
fn visit_assoc_domain<R: Relation>(&mut self, _: &AssocDomain<R>);
|
|
|
|
+ /// Visit an instance of the range side of a bidirectional relation map.
|
|
fn visit_assoc_range<R: Relation>(&mut self, _: &AssocRange<R>);
|
|
fn visit_assoc_range<R: Relation>(&mut self, _: &AssocRange<R>);
|
|
}
|
|
}
|
|
|
|
|
|
/// A fixed-length list of EntityDatums, usually a tuple.
|
|
/// A fixed-length list of EntityDatums, usually a tuple.
|
|
pub trait DatumList: Clone {
|
|
pub trait DatumList: Clone {
|
|
|
|
+ /// Accept a datum visitor for iteration.
|
|
fn accept(&self, visitor: &mut impl DatumVisitor);
|
|
fn accept(&self, visitor: &mut impl DatumVisitor);
|
|
-
|
|
|
|
- const LEN: usize;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/// A list of concrete datums.
|
|
/// A list of concrete datums.
|
|
pub trait ConcreteDatumList: DatumList + Clone {
|
|
pub trait ConcreteDatumList: DatumList + Clone {
|
|
|
|
+ /// Construct a [`DatumList`] that is _query-equivalent_ of the current type. See
|
|
|
|
+ /// [`QueryEquivalent`] and [`QueryEquivalentList`] for more information.
|
|
fn build_equivalent<'l>(
|
|
fn build_equivalent<'l>(
|
|
from: impl Iterator<Item = &'l str>,
|
|
from: impl Iterator<Item = &'l str>,
|
|
) -> Option<impl QueryEquivalentList<Self> + 'l>;
|
|
) -> Option<impl QueryEquivalentList<Self> + 'l>;
|
|
}
|
|
}
|
|
|
|
|
|
-/// A walker for a DatumList instance.
|
|
|
|
|
|
+/// A walker for DatumList instances.
|
|
pub trait DatumVisitor {
|
|
pub trait DatumVisitor {
|
|
|
|
+ /// Visit a specific datum in a DatumList.
|
|
fn visit<ED: Datum>(&mut self, datum: &ED);
|
|
fn visit<ED: Datum>(&mut self, datum: &ED);
|
|
}
|
|
}
|
|
|
|
|