use toasty_core::schema::app;
pub(super) fn flatten_relation_path(
schema: &toasty_core::Schema,
source_model_id: app::ModelId,
initial_steps: &[usize],
) -> Vec<app::FieldId> {
let mut result = Vec::with_capacity(initial_steps.len());
let mut current_model = source_model_id;
let mut queue: Vec<usize> = initial_steps.to_vec();
queue.reverse();
while let Some(index) = queue.pop() {
let field = &schema.app.model(current_model).as_root_unwrap().fields[index];
let field_id = app::FieldId {
model: current_model,
index,
};
if let app::FieldTy::Via(via) = &field.ty {
debug_assert_eq!(via.path.root.as_model(), Some(current_model));
for step in via_relation_steps(via).iter().rev() {
queue.push(*step);
}
continue;
}
current_model = field
.relation_target_id()
.expect("relation path step is not a relation");
result.push(field_id);
}
result
}
pub(super) fn flatten_via_path(
schema: &toasty_core::Schema,
via: &app::Via,
) -> Option<Vec<app::FieldId>> {
let root = via.path.root.as_model()?;
Some(flatten_relation_path(schema, root, via_relation_steps(via)))
}
fn via_relation_steps(via: &app::Via) -> &[usize] {
let projection = via.path.projection.as_slice();
match via.terminal {
Some(_) => &projection[..projection.len() - 1],
None => projection,
}
}