use crate::item::Item; /// Collect database results into a `Vec<_>` #[macro_export] macro_rules! collect_results { ($res:expr) => {{ use futures::stream::TryStreamExt; let mut ret = vec![]; while let Some(doc) = $res.try_next().await.unwrap() { ret.push(doc); } ret }}; } /// Get a database collection #[macro_export] macro_rules! cdb_col { ($db:expr, $col:expr) => { $db.database("cdb") .collection::($col) }; } /// Get a MongoDB Client from the environment #[macro_export] macro_rules! get_mongo { () => { mongodb::Client::with_uri_str(std::env::var("DB_URI").unwrap()) .await .unwrap() }; } /// MongoDB filter for the `_id` field. #[macro_export] macro_rules! id_of { ($id:expr) => { doc! { "_id": $id} }; } /// Item database pub struct ItemDB { index: mdq::Index, } impl ItemDB { /// Create a new item database using `dir` as the base. /// /// The directory should contain markdown documents with valid frontmatter to be parsed into `Item`s pub async fn new(dir: &str) -> Self { // scan for markdown item entries let index = mdq::Index::new(dir, true); let mongodb = get_mongo!(); for item in &index.documents { let item = Item::new(item); item.init_db(&mongodb).await; } Self { index } } /// Retrieves an item by name pub fn get_item(&self, item: &str) -> Option { Some( self.index .documents .iter() .map(Item::new) // <-- todo : performance? .find(|x| x.name == item)?, ) } /// Get all items pub fn items(&self) -> Vec { let mut ret = vec![]; for item in &self.index.documents { let item = Item::new(item); ret.push(item.name); } ret } }