///|
fn contains_folded(text : String, term : String) -> Bool {
text.to_lower().contains(term.to_lower())
}
///|
pub fn search_entities(index : ModelIndex, term : String) -> Array[SearchHit] {
let hits : Array[SearchHit] = []
for entity in index.all() {
if contains_folded(entity.name, term) {
hits.push(SearchHit::{
entity_id: entity.id,
product_id: None,
field: EntityType,
value: entity.name,
})
}
for argument in entity.arguments {
let text = argument.to_step_lossless()
if contains_folded(text, term) {
hits.push(SearchHit::{
entity_id: entity.id,
product_id: None,
field: EntityText,
value: text,
})
}
}
}
hits
}
///|
fn product_search_hit(
product : Product,
field : SearchField,
value : String,
) -> SearchHit {
SearchHit::{
entity_id: product.id,
product_id: Some(product.id),
field,
value,
}
}
///|
pub fn search_products(
index : ModelIndex,
field : SearchField,
term : String,
) -> Array[SearchHit] {
let hits : Array[SearchHit] = []
for product in extract_products(index) {
match field {
ProductName =>
match product.name {
Some(value) if contains_folded(value, term) =>
hits.push(product_search_hit(product, field, value))
_ => ()
}
ProductGlobalId =>
match product.global_id {
Some(value) if contains_folded(value, term) =>
hits.push(product_search_hit(product, field, value))
_ => ()
}
ProductTag =>
match product.tag {
Some(value) if contains_folded(value, term) =>
hits.push(product_search_hit(product, field, value))
_ => ()
}
EntityType if contains_folded(product.ifc_type, term) =>
hits.push(product_search_hit(product, field, product.ifc_type))
_ => ()
}
}
hits
}
///|
pub fn search_properties(
index : ModelIndex,
term : String,
) -> Array[SearchHit] raise ParseError {
let hits : Array[SearchHit] = []
for property_set in all_property_sets(index) {
for property in property_set.properties {
let name_match = contains_folded(property.name, term)
let value_text = property.value.to_step_lossless()
let value_match = contains_folded(value_text, term)
if name_match || value_match {
hits.push(SearchHit::{
entity_id: property_set.id,
product_id: None,
field: if name_match {
PropertyName
} else {
PropertyValue
},
value: if name_match {
property.name
} else {
value_text
},
})
}
}
}
hits
}
///|
pub fn search(
model : Model,
field : SearchField,
term : String,
) -> Array[SearchHit] raise ParseError {
let index = model.index()
match field {
EntityType | EntityText => search_entities(index, term)
ProductName | ProductGlobalId | ProductTag =>
search_products(index, field, term)
PropertyName | PropertyValue => search_properties(index, term)
}
}
///|
pub fn search_first_product(
index : ModelIndex,
field : SearchField,
term : String,
) -> Product? {
let hits = search_products(index, field, term)
match hits.get(0) {
Some(hit) =>
match hit.product_id {
Some(id) => product_by_id(extract_products(index), id)
None => None
}
None => None
}
}