///|
pub(all) struct ModelIndex {
entities : Array[Entity]
by_id : Map[Int, Entity]
by_name : Map[String, Array[Int]]
} derive(Debug)
///|
pub fn Model::index(self : Model) -> ModelIndex {
let by_id : Map[Int, Entity] = Map([])
let by_name : Map[String, Array[Int]] = Map([])
for entity in self.entities {
by_id[entity.id] = entity
let key = entity.name.to_upper()
match by_name.get(key) {
Some(ids) => ids.push(entity.id)
None => by_name[key] = [entity.id]
}
}
{ entities: self.entities, by_id, by_name }
}
///|
pub fn ModelIndex::entity(self : ModelIndex, id : Int) -> Entity? {
self.by_id.get(id)
}
///|
pub fn ModelIndex::require(
self : ModelIndex,
id : Int,
) -> Entity raise ParseError {
match self.by_id.get(id) {
Some(entity) => entity
None =>
raise ParseError::InvalidReference(
position=SourcePosition::{ offset: 0, line: 0, column: 0 },
text="#" + id.to_string(),
)
}
}
///|
pub fn ModelIndex::ids_named(self : ModelIndex, name : String) -> Array[Int] {
self.by_name.get(name.to_upper()).unwrap_or([])
}
///|
pub fn ModelIndex::entities_named(
self : ModelIndex,
name : String,
) -> Array[Entity] {
self
.ids_named(name)
.fold(init=Array::new(), (result, id) => {
match self.by_id.get(id) {
Some(entity) => {
result.push(entity)
result
}
None => result
}
})
}
///|
pub fn ModelIndex::all(self : ModelIndex) -> Array[Entity] {
self.entities
}
///|
pub fn ModelIndex::has(self : ModelIndex, id : Int) -> Bool {
self.by_id.contains(id)
}
///|
pub fn entity_value(entity : Entity, index : Int) -> Value? {
entity.arguments.get(index)
}
///|
pub fn value_reference(value : Value?) -> Int? {
match value {
Some(item) => item.as_reference()
None => None
}
}
///|
pub fn references(value : Value) -> Array[Int] {
match value {
Reference(id) => [id]
List(values) =>
values.fold(init=Array::new(), (result, item) => {
for id in references(item) {
result.push(id)
}
result
})
Typed(name~, value~) => {
ignore(name)
references(value)
}
_ => []
}
}
///|
pub fn entity_references(entity : Entity) -> Array[Int] {
entity.arguments.fold(init=Array::new(), (result, value) => {
for id in references(value) {
result.push(id)
}
result
})
}