use lunar_lib::database::{
CompareAndSwapTransaction, Createable, CustomTransactionError, DatabaseEntry, TransactionError,
caching::Cacheable,
};
use crate::{
database::{COLLECTION_CACHE, LibraryDb},
library::{
collectable::Collectable,
collection::{
Collection, CollectionCreationError, CollectionId, CollectionType,
DynamicCollectionRules,
},
},
};
impl DatabaseEntry for Collection {
type Id = CollectionId;
type Db = LibraryDb;
const VERSION_NUMBER: u32 = 1;
const TREE_NAME: &str = "collection";
fn id(&self) -> Self::Id {
self.id
}
fn read_only(&self) -> bool {
self.read_only
}
}
impl Cacheable for Collection {
fn cache() -> &'static std::sync::Mutex<lunar_lib::database::caching::DbCache<Self>> {
&COLLECTION_CACHE
}
}
#[derive(Debug, Clone)]
pub struct CollectionCreateArgs {
name: String,
collection_type: CollectionType,
}
impl CollectionCreateArgs {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
collection_type: CollectionType::Static {
collectables: Vec::new(),
},
}
}
#[must_use]
pub fn with_items(mut self, items: Vec<Collectable>) -> Self {
self.collection_type = CollectionType::Static {
collectables: items,
};
self
}
#[must_use]
pub fn with_rules(mut self, rules: Vec<DynamicCollectionRules>) -> Self {
self.collection_type = CollectionType::Dynamic { rules };
self
}
}
impl Createable for Collection {
type CreateArgs = CollectionCreateArgs;
type Err = CollectionCreationError;
fn tx_create(
cas_tx: &mut CompareAndSwapTransaction<Self::Db>,
args: Self::CreateArgs,
) -> Result<Self, CustomTransactionError<Self::Err>> {
let mut collection =
Collection::new_static(args.name).map_err(CustomTransactionError::Closure)?;
if cas_tx.tx_get(collection.id())?.is_some() {
return Err(TransactionError::AlreadyInDatabase.into());
}
collection.items = args.collection_type;
Ok(collection)
}
}