Trait bound RelationBuilder

This commit is contained in:
Chris Tsang 2021-05-17 23:28:58 +08:00
parent 682d2151fc
commit acdee45744
2 changed files with 27 additions and 22 deletions

View File

@ -2,7 +2,7 @@ use crate::{
ColumnTrait, ModelTrait, PrimaryKeyOfModel, PrimaryKeyTrait, QueryHelper, RelationBuilder, ColumnTrait, ModelTrait, PrimaryKeyOfModel, PrimaryKeyTrait, QueryHelper, RelationBuilder,
RelationTrait, RelationType, Select, RelationTrait, RelationType, Select,
}; };
use sea_query::{Iden, IntoIden, Value}; use sea_query::{Iden, Value};
use std::fmt::Debug; use std::fmt::Debug;
pub use strum::IntoEnumIterator as Iterable; pub use strum::IntoEnumIterator as Iterable;
@ -25,16 +25,16 @@ pub trait EntityTrait: EntityName {
true true
} }
fn has_one<E>(entity: E) -> RelationBuilder fn has_one<R>(entity: R) -> RelationBuilder<Self, R>
where where
E: IntoIden, R: EntityTrait,
{ {
RelationBuilder::new(RelationType::HasOne, Self::default(), entity) RelationBuilder::new(RelationType::HasOne, Self::default(), entity)
} }
fn has_many<E>(entity: E) -> RelationBuilder fn has_many<R>(entity: R) -> RelationBuilder<Self, R>
where where
E: IntoIden, R: EntityTrait,
{ {
RelationBuilder::new(RelationType::HasMany, Self::default(), entity) RelationBuilder::new(RelationType::HasMany, Self::default(), entity)
} }

View File

@ -1,4 +1,5 @@
use crate::{EntityTrait, Identity, IntoIdentity, Select}; use crate::{EntityTrait, Identity, IntoIdentity, Select};
use core::marker::PhantomData;
use sea_query::{Iden, IntoIden, JoinType}; use sea_query::{Iden, IntoIden, JoinType};
use std::fmt::Debug; use std::fmt::Debug;
use std::rc::Rc; use std::rc::Rc;
@ -36,7 +37,12 @@ pub struct RelationDef {
pub to_col: Identity, pub to_col: Identity,
} }
pub struct RelationBuilder { pub struct RelationBuilder<E, R>
where
E: EntityTrait,
R: EntityTrait,
{
entities: PhantomData<(E, R)>,
rel_type: RelationType, rel_type: RelationType,
from_tbl: Rc<dyn Iden>, from_tbl: Rc<dyn Iden>,
to_tbl: Rc<dyn Iden>, to_tbl: Rc<dyn Iden>,
@ -44,13 +50,14 @@ pub struct RelationBuilder {
to_col: Option<Identity>, to_col: Option<Identity>,
} }
impl RelationBuilder { impl<E, R> RelationBuilder<E, R>
pub(crate) fn new<E, T>(rel_type: RelationType, from: E, to: T) -> Self where
where E: EntityTrait,
E: IntoIden, R: EntityTrait,
T: IntoIden, {
{ pub(crate) fn new(rel_type: RelationType, from: E, to: R) -> Self {
Self { Self {
entities: PhantomData,
rel_type, rel_type,
from_tbl: from.into_iden(), from_tbl: from.into_iden(),
to_tbl: to.into_iden(), to_tbl: to.into_iden(),
@ -59,25 +66,23 @@ impl RelationBuilder {
} }
} }
pub fn from<T>(mut self, identifier: T) -> Self pub fn from(mut self, identifier: E::Column) -> Self {
where
T: IntoIdentity,
{
self.from_col = Some(identifier.into_identity()); self.from_col = Some(identifier.into_identity());
self self
} }
pub fn to<T>(mut self, identifier: T) -> Self pub fn to(mut self, identifier: R::Column) -> Self {
where
T: IntoIdentity,
{
self.to_col = Some(identifier.into_identity()); self.to_col = Some(identifier.into_identity());
self self
} }
} }
impl From<RelationBuilder> for RelationDef { impl<E, R> From<RelationBuilder<E, R>> for RelationDef
fn from(b: RelationBuilder) -> Self { where
E: EntityTrait,
R: EntityTrait,
{
fn from(b: RelationBuilder<E, R>) -> Self {
RelationDef { RelationDef {
rel_type: b.rel_type, rel_type: b.rel_type,
from_tbl: b.from_tbl, from_tbl: b.from_tbl,