use std::fmt::Display;
use crate::{
relations::{ManyToManyRelationId, Relation, RelationAttributes},
walkers::{ModelWalker, RelationFieldWalker, RelationName, RelationWalker, Walker},
};
pub type ImplicitManyToManyRelationWalker<'db> = Walker<'db, ManyToManyRelationId>;
impl<'db> ImplicitManyToManyRelationWalker<'db> {
fn get(&self) -> &'db Relation {
&self.db.relations[self.id.0]
}
pub fn is_self_relation(self) -> bool {
let rel = self.get();
rel.model_a == rel.model_b
}
pub fn model_a(self) -> ModelWalker<'db> {
self.db.walk(self.get().model_a)
}
pub fn model_b(self) -> ModelWalker<'db> {
self.db.walk(self.get().model_b)
}
pub fn field_a(self) -> RelationFieldWalker<'db> {
let rel = self.get();
match rel.attributes {
RelationAttributes::ImplicitManyToMany { field_a, field_b: _ } => self.walk(field_a),
_ => unreachable!(),
}
}
pub fn field_b(self) -> RelationFieldWalker<'db> {
let rel = self.get();
match rel.attributes {
RelationAttributes::ImplicitManyToMany { field_a: _, field_b } => self.walk(field_b),
_ => unreachable!(),
}
}
pub fn as_relation(self) -> RelationWalker<'db> {
self.db.walk(self.id.0)
}
pub fn relation_name(self) -> RelationName<'db> {
self.field_a().relation_name()
}
pub fn column_a_name(self) -> &'static str {
"A"
}
pub fn column_b_name(self) -> &'static str {
"B"
}
pub fn table_name(self) -> ImplicitManyToManyRelationTableName<'db> {
ImplicitManyToManyRelationTableName(self.relation_name())
}
}
pub struct ImplicitManyToManyRelationTableName<'db>(RelationName<'db>);
impl Display for ImplicitManyToManyRelationTableName<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("_")?;
Display::fmt(&self.0, f)
}
}