From 830faf74247ee225aa5c5884caaf2b55c409cbce Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Wed, 2 Sep 2020 17:24:49 -0400 Subject: [PATCH] DB: No more Arcs! --- youmubot-db/src/lib.rs | 58 ++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/youmubot-db/src/lib.rs b/youmubot-db/src/lib.rs index af734f0..51c7db6 100644 --- a/youmubot-db/src/lib.rs +++ b/youmubot-db/src/lib.rs @@ -1,15 +1,19 @@ -use rustbreak::{deser::Yaml as Ron, FileDatabase}; +use rustbreak::{deser::Yaml, FileDatabase}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serenity::{framework::standard::CommandError as Error, model::id::GuildId, prelude::*}; -use std::collections::HashMap; -use std::{cell::Cell, path::Path, sync::Arc}; +use std::{collections::HashMap, path::Path}; + /// GuildMap defines the guild-map type. /// It is basically a HashMap from a GuildId to a data structure. pub type GuildMap = HashMap; /// The generic DB type we will be using. pub struct DB(std::marker::PhantomData); -impl serenity::prelude::TypeMapKey for DB { - type Value = Arc>; + +/// A short type abbreviation for a FileDatabase. +type Database = FileDatabase; + +impl serenity::prelude::TypeMapKey for DB { + type Value = Database; } impl DB @@ -17,66 +21,64 @@ where for<'de> T: Deserialize<'de>, { /// Insert into a ShareMap. - pub fn insert_into(data: &mut ShareMap, path: impl AsRef) -> Result<(), Error> { - let db = FileDatabase::::from_path(path, T::default())?; - db.load().or_else(|e| { - dbg!(e); - db.save() - })?; - data.insert::>(Arc::new(db)); + pub fn insert_into(data: &mut TypeMap, path: impl AsRef) -> Result<(), Error> { + let db = Database::::load_from_path_or_default(path)?; + data.insert::>(db); Ok(()) } /// Open a previously inserted DB. - pub fn open(data: &ShareMap) -> DBWriteGuard { - data.get::().expect("DB initialized").clone().into() + pub fn open(data: &TypeMap) -> DBWriteGuard { + data.get::().expect("DB initialized").into() } } /// The write guard for our FileDatabase. /// It wraps the FileDatabase in a write-on-drop lock. #[derive(Debug)] -pub struct DBWriteGuard +pub struct DBWriteGuard<'a, T> where T: Send + Sync + Clone + std::fmt::Debug + Serialize + DeserializeOwned, { - db: Arc>, - needs_save: Cell, + db: &'a Database, + needs_save: bool, } -impl From>> for DBWriteGuard +impl<'a, T> From<&'a Database> for DBWriteGuard<'a, T> where T: Send + Sync + Clone + std::fmt::Debug + Serialize + DeserializeOwned, { - fn from(v: Arc>) -> Self { + fn from(v: &'a Database) -> Self { DBWriteGuard { db: v, - needs_save: Cell::new(false), + needs_save: false, } } } -impl DBWriteGuard +impl<'a, T> DBWriteGuard<'a, T> where T: Send + Sync + Clone + std::fmt::Debug + Serialize + DeserializeOwned, { /// Borrows the FileDatabase. - pub fn borrow(&self) -> Result, rustbreak::RustbreakError> { - (*self).db.borrow_data() + pub fn borrow(&'a self) -> Result, rustbreak::RustbreakError> { + self.db.borrow_data() } /// Borrows the FileDatabase for writing. - pub fn borrow_mut(&self) -> Result, rustbreak::RustbreakError> { - self.needs_save.set(true); - (*self).db.borrow_data_mut() + pub fn borrow_mut( + &'a mut self, + ) -> Result, rustbreak::RustbreakError> { + self.needs_save = true; + self.db.borrow_data_mut() } } -impl Drop for DBWriteGuard +impl<'a, T> Drop for DBWriteGuard<'a, T> where T: Send + Sync + Clone + std::fmt::Debug + Serialize + DeserializeOwned, { fn drop(&mut self) { - if self.needs_save.get() { + if self.needs_save { if let Err(e) = self.db.save() { dbg!(e); }