use toasty::schema::app;
use super::ModelId;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct BelongsTo {
pub(crate) name: String,
pub(crate) target: ModelId,
pub(crate) foreign_keys: Vec<String>,
}
pub(crate) fn belongs_to<M: toasty::schema::Model>(index: usize) -> Option<BelongsTo> {
let model = M::schema();
let root = model.as_root()?;
let field = root.fields.get(index)?;
let app::FieldTy::BelongsTo(relation) = &field.ty else {
return None;
};
let foreign_keys = relation
.foreign_key
.fields
.iter()
.filter_map(|key| root.fields.get(key.source.index))
.map(|field| field.name.app_unwrap().to_string())
.collect::<Vec<_>>();
(!foreign_keys.is_empty()).then(|| BelongsTo {
name: field.name.app_unwrap().to_string(),
target: relation.target,
foreign_keys,
})
}
pub(crate) fn belongs_tos<M: toasty::schema::Model>() -> Vec<BelongsTo> {
let count = M::schema().as_root().map_or(0, |root| root.fields.len());
(0..count).filter_map(belongs_to::<M>).collect()
}
pub(crate) fn label_name<'a>(field: &'a app::Field, root: &'a app::ModelRoot) -> &'a str {
let name = field.name.app_unwrap();
root.fields
.iter()
.find_map(|relation| match &relation.ty {
app::FieldTy::BelongsTo(belongs_to) => match belongs_to.foreign_key.fields.as_slice() {
[key] if key.source == field.id => relation.name.app.as_deref(),
_ => None,
},
_ => None,
})
.unwrap_or(name)
}