use toasty::schema::app;
use super::{MappingField, app_embedded};
pub(super) fn app_field_at<'a>(
schema: &'a toasty_core::Schema,
fields: &'a [app::Field],
steps: &[usize],
) -> Option<&'a app::Field> {
let (first, rest) = steps.split_first()?;
let field = fields.get(*first)?;
if rest.is_empty() {
return Some(field);
}
match app_embedded(schema, field)? {
app::Model::EmbeddedStruct(e) => app_field_at(schema, &e.fields, rest),
app::Model::EmbeddedEnum(e) => {
let (variant, tail) = rest.split_first()?;
e.variants.get(*variant)?;
let field = e.variant_fields(*variant).get(*tail.first()?)?;
if tail.len() == 1 {
Some(field)
} else {
app_field_at(schema, std::slice::from_ref(field), &tail[1..])
}
}
app::Model::Root(_) => None,
}
}
pub(super) fn mapping_field_at<'a>(
fields: &'a [MappingField],
steps: &[usize],
) -> Option<&'a MappingField> {
let (first, rest) = steps.split_first()?;
let field = fields.get(*first)?;
if rest.is_empty() {
return Some(field);
}
match field {
MappingField::Struct(s) => mapping_field_at(&s.fields, rest),
MappingField::Enum(e) => {
let (variant, tail) = rest.split_first()?;
mapping_field_at(&e.variants.get(*variant)?.fields, tail)
}
_ => None,
}
}