mod attribute;
mod composite_type;
mod datasource;
mod r#enum;
mod expression;
mod field;
mod generator;
mod model;
mod property;
pub use attribute::AttributePosition;
pub use composite_type::CompositeTypePosition;
pub use datasource::SourcePosition;
pub use r#enum::{EnumPosition, EnumValuePosition};
pub use expression::ExpressionPosition;
pub use field::FieldPosition;
pub use generator::GeneratorPosition;
pub use model::ModelPosition;
pub use property::PropertyPosition;
use crate::ast::{self, top_idx_to_top_id, traits::*};
impl ast::SchemaAst {
pub fn find_at_position(&self, position: usize) -> SchemaPosition<'_> {
self.find_top_at_position(position)
.map(|top_id| match top_id {
ast::TopId::Model(model_id) => {
SchemaPosition::Model(model_id, ModelPosition::new(&self[model_id], position))
}
ast::TopId::Enum(enum_id) => SchemaPosition::Enum(enum_id, EnumPosition::new(&self[enum_id], position)),
ast::TopId::CompositeType(composite_type_id) => SchemaPosition::CompositeType(
composite_type_id,
CompositeTypePosition::new(&self[composite_type_id], position),
),
ast::TopId::Source(source_id) => {
SchemaPosition::DataSource(source_id, SourcePosition::new(&self[source_id], position))
}
ast::TopId::Generator(generator_id) => {
SchemaPosition::Generator(generator_id, GeneratorPosition::new(&self[generator_id], position))
}
})
.unwrap_or(SchemaPosition::TopLevel)
}
pub fn find_top_at_position(&self, position: usize) -> Option<ast::TopId> {
use std::cmp::Ordering;
let top_idx = self.tops.binary_search_by(|top| {
let span = top.span();
if span.start > position {
Ordering::Greater
} else if span.end < position {
Ordering::Less
} else {
Ordering::Equal
}
});
top_idx.map(|idx| top_idx_to_top_id(idx, &self.tops[idx])).ok()
}
}
#[derive(Debug)]
pub enum SchemaPosition<'ast> {
TopLevel,
Model(ast::ModelId, ModelPosition<'ast>),
Enum(ast::EnumId, EnumPosition<'ast>),
CompositeType(ast::CompositeTypeId, CompositeTypePosition<'ast>),
DataSource(ast::SourceId, SourcePosition<'ast>),
Generator(ast::GeneratorId, GeneratorPosition<'ast>),
}