use crate::schema::{Model, RelationOneField};
use crate::stmt::Path;
use toasty_core::schema::Name;
use toasty_core::schema::app::{self, FieldTy, Via};
use toasty_core::stmt;
#[diagnostic::on_unimplemented(
message = "`#[has_one(via = ...)]` result `{Self}` cannot traverse a step targeting `{Step}`",
label = "incompatible via step",
note = "a required via cannot traverse optional relations; declare the via field as `Option<_>` or `Deferred<Option<_>>`"
)]
pub trait AllowsViaStep<Step> {}
#[diagnostic::do_not_recommend]
impl<Declared: Model, Step: Model> AllowsViaStep<Step> for Declared {}
#[diagnostic::do_not_recommend]
impl<Declared: Model, Step: Model> AllowsViaStep<Step> for Option<Declared> {}
#[diagnostic::do_not_recommend]
impl<Declared: Model, Step: Model> AllowsViaStep<Option<Step>> for Option<Declared> {}
pub fn check_one_step<F, Origin, Target>(_: &impl Into<Path<Origin, Target>>)
where
F: RelationOneField,
F::Expr: AllowsViaStep<Target>,
Target: RelationOneField,
{
}
pub fn into_one_path<F, Origin, Target>(path: Path<Origin, Target>) -> stmt::Path
where
F: RelationOneField,
Target: RelationOneField<Target = F::Target>,
{
path.into()
}
pub fn model_via_field_ty<M: Model>(singular: Name, path: stmt::Path) -> FieldTy {
let target = <M as Model>::id();
let expr_ty = stmt::Type::List(Box::new(stmt::Type::Model(target)));
FieldTy::Via(Via::new(
target,
expr_ty,
app::Cardinality::Many { singular },
path,
None,
))
}