use crate::{
ast,
types::IdAttribute,
walkers::{ModelWalker, ScalarFieldAttributeWalker, ScalarFieldWalker},
ParserDatabase, ScalarFieldId,
};
#[derive(Copy, Clone)]
pub struct PrimaryKeyWalker<'db> {
pub(crate) model_id: ast::ModelId,
pub(crate) attribute: &'db IdAttribute,
pub(crate) db: &'db ParserDatabase,
}
impl<'db> PrimaryKeyWalker<'db> {
pub fn ast_attribute(self) -> &'db ast::Attribute {
&self.db.ast[self.attribute.source_attribute]
}
pub fn mapped_name(self) -> Option<&'db str> {
self.attribute.mapped_name.map(|id| &self.db[id])
}
pub fn is_defined_on_field(self) -> bool {
self.attribute.source_field.is_some()
}
pub fn attribute_name(self) -> &'static str {
if self.is_defined_on_field() {
"@id"
} else {
"@@id"
}
}
pub fn clustered(self) -> Option<bool> {
self.attribute.clustered
}
pub fn model(self) -> ModelWalker<'db> {
self.db.walk(self.model_id)
}
pub fn name(self) -> Option<&'db str> {
self.attribute.name.map(|id| &self.db[id])
}
pub fn fields(self) -> impl ExactSizeIterator<Item = ScalarFieldWalker<'db>> + Clone + 'db {
self.attribute
.fields
.iter()
.map(move |field| self.db.walk(field.path.root()))
}
pub fn scalar_field_attributes(self) -> impl ExactSizeIterator<Item = ScalarFieldAttributeWalker<'db>> + 'db {
self.attribute
.fields
.iter()
.enumerate()
.map(move |(field_arg_id, _)| ScalarFieldAttributeWalker {
fields: &self.attribute.fields,
db: self.db,
field_arg_id,
})
}
pub(crate) fn contains_exactly_fields_by_id(self, fields: &[ScalarFieldId]) -> bool {
self.attribute.fields.len() == fields.len()
&& self
.attribute
.fields
.iter()
.zip(fields)
.all(|(a, b)| matches!(a.path.field_in_index(), either::Either::Left(id) if id == *b))
}
pub fn contains_exactly_fields(self, fields: impl ExactSizeIterator<Item = ScalarFieldWalker<'db>>) -> bool {
self.attribute.fields.len() == fields.len() && self.fields().zip(fields).all(|(a, b)| a == b)
}
}