use crate::types::{Brand, CatalogFile, Interaction, Product};
const EMBEDDED_CATALOG: &str = include_str!("../data/catalog.toml");
pub fn load_catalog() -> CatalogFile {
toml::from_str(EMBEDDED_CATALOG).expect("embedded catalog.toml is invalid")
}
pub fn find_product<'a>(catalog: &'a CatalogFile, id: &str) -> Option<&'a Product> {
catalog.product.iter().find(|p| p.id == id)
}
pub fn find_brand<'a>(catalog: &'a CatalogFile, id: &str) -> Option<&'a Brand> {
catalog.brand.iter().find(|b| b.id == id)
}
pub fn products_for_biomarker<'a>(catalog: &'a CatalogFile, biomarker: &str) -> Vec<&'a Product> {
let bio_lower = biomarker.to_lowercase();
catalog
.product
.iter()
.filter(|p| {
p.targets
.iter()
.any(|t| t.biomarker.to_lowercase() == bio_lower)
})
.collect()
}
pub fn products_by_category<'a>(catalog: &'a CatalogFile, category: &str) -> Vec<&'a Product> {
let cat_lower = category.to_lowercase();
catalog
.product
.iter()
.filter(|p| p.category.to_lowercase() == cat_lower)
.collect()
}
pub fn products_by_brand<'a>(catalog: &'a CatalogFile, brand_id: &str) -> Vec<&'a Product> {
let bid_lower = brand_id.to_lowercase();
catalog
.product
.iter()
.filter(|p| p.brand_id.to_lowercase() == bid_lower)
.collect()
}
pub fn search_products<'a>(catalog: &'a CatalogFile, query: &str) -> Vec<&'a Product> {
let q = query.to_lowercase();
catalog
.product
.iter()
.filter(|p| {
p.name.to_lowercase().contains(&q)
|| p.category.to_lowercase().contains(&q)
|| p.brand_id.to_lowercase().contains(&q)
|| p.description.to_lowercase().contains(&q)
|| p.id.to_lowercase().contains(&q)
|| p.targets
.iter()
.any(|t| t.biomarker.to_lowercase().contains(&q) || t.mechanism.to_lowercase().contains(&q))
})
.collect()
}
pub fn find_interactions<'a>(catalog: &'a CatalogFile, ids: &[&str]) -> Vec<&'a Interaction> {
catalog
.interaction
.iter()
.filter(|i| {
let a_in = ids.contains(&i.product_a.as_str());
let b_in = ids.contains(&i.product_b.as_str());
a_in && b_in
})
.collect()
}