use once_cell::sync::OnceCell; use polodb_core::{ bson::{doc, Regex}, Database, }; use serde::{Deserialize, Serialize}; use std::io::{Error, ErrorKind}; pub static DB: OnceCell = OnceCell::new(); #[derive(Default, Debug, Serialize, Deserialize)] pub struct Technology { pub link: String, pub name: String, pub tags: Vec, } #[derive(Debug, Serialize, Deserialize)] struct AuthorizedUser { discord_id: String, } /// Add a new technology to the database. pub fn add_tech(name: &str, link: &str, tags: &[&str]) -> Result<(), Error> { DB.get() .unwrap() .collection::("technologies") .insert_one(Technology { link: link.into(), name: name.into(), tags: tags.iter().map(|s| s.to_string()).collect(), }) .map_err(|err| Error::new(ErrorKind::InvalidInput, err))?; Ok(()) } pub fn remove_tech(name: String) -> Result<(), Error> { DB.get() .unwrap() .collection::("technologies") .delete_one(doc! { "name": name }) .map_err(|err| Error::new(ErrorKind::InvalidInput, err))?; Ok(()) } pub fn list_tech() -> Result, Error> { Ok(DB .get() .unwrap() .collection("technologies") .find(None) .map_err(|err| Error::new(ErrorKind::InvalidInput, err))? .filter(|doc| doc.is_ok()) .map(|doc| doc.unwrap()) .collect()) } pub fn search_tech(name: String, options: String, tags: &[&str]) -> Result, Error> { Ok(DB .get() .unwrap() .collection::("technologies") .find(doc! { "name": {"$regex": Regex { pattern: name, options: options, }}, "tags": { "$in": tags } }) .map_err(|err| Error::new(ErrorKind::InvalidInput, err))? .map( |doc| doc.unwrap(), // todo: find a way to handle error ) .collect::>()) } pub fn set_auth_user(discord_id: String) -> Result<(), Error> { DB.get() .unwrap() .collection("authorized_users") .insert_one(AuthorizedUser { discord_id }) .map_err(|err| Error::new(ErrorKind::InvalidInput, err))?; Ok(()) } pub fn is_auth_user(discord_id: String) -> Result { Ok(DB .get() .unwrap() .collection::("authorized_users") .find(doc! { "$eq": [{"discord_id": discord_id}] }) .map_err(|err| Error::new(ErrorKind::InvalidInput, err))? .next() .is_some()) }