use crate::types::{Device, DeviceBrand, DeviceCatalogFile};
const EMBEDDED_CATALOG: &str = include_str!("../data/catalog.toml");
pub fn load_catalog() -> DeviceCatalogFile {
toml::from_str(EMBEDDED_CATALOG).expect("embedded catalog.toml is invalid")
}
pub fn find_device<'a>(catalog: &'a DeviceCatalogFile, id: &str) -> Option<&'a Device> {
catalog.device.iter().find(|d| d.id == id)
}
pub fn find_brand<'a>(catalog: &'a DeviceCatalogFile, id: &str) -> Option<&'a DeviceBrand> {
catalog.brand.iter().find(|b| b.id == id)
}
pub fn devices_tracking_metric<'a>(
catalog: &'a DeviceCatalogFile,
metric: &str,
) -> Vec<&'a Device> {
let lower = metric.to_lowercase();
catalog
.device
.iter()
.filter(|d| d.tracks.iter().any(|t| t.metric.to_lowercase() == lower))
.collect()
}
pub fn devices_by_category<'a>(
catalog: &'a DeviceCatalogFile,
category: &str,
) -> Vec<&'a Device> {
let lower = category.to_lowercase();
catalog
.device
.iter()
.filter(|d| d.category.to_lowercase() == lower)
.collect()
}
pub fn devices_by_brand<'a>(catalog: &'a DeviceCatalogFile, brand_id: &str) -> Vec<&'a Device> {
let lower = brand_id.to_lowercase();
catalog
.device
.iter()
.filter(|d| d.brand_id.to_lowercase() == lower)
.collect()
}
pub fn devices_by_price_range<'a>(
catalog: &'a DeviceCatalogFile,
price_range: &str,
) -> Vec<&'a Device> {
let lower = price_range.to_lowercase();
catalog
.device
.iter()
.filter(|d| d.price_range.to_lowercase() == lower)
.collect()
}
pub fn search_devices<'a>(catalog: &'a DeviceCatalogFile, query: &str) -> Vec<&'a Device> {
let lower = query.to_lowercase();
catalog
.device
.iter()
.filter(|d| {
d.name.to_lowercase().contains(&lower)
|| d.id.to_lowercase().contains(&lower)
|| d.category.to_lowercase().contains(&lower)
|| d.brand_id.to_lowercase().contains(&lower)
|| d.description.to_lowercase().contains(&lower)
|| d.tracks
.iter()
.any(|t| t.metric.to_lowercase().contains(&lower))
|| d.use_cases
.iter()
.any(|u| u.to_lowercase().contains(&lower))
|| d.notes.to_lowercase().contains(&lower)
})
.collect()
}