use std::convert::Infallible;
use lunar_lib::database::{
CompareAndSwapTransaction, CustomTransactionError, DatabaseEntry, DatabaseError,
TransactionError, Tree,
};
use crate::{
database::{Createable, LibraryDb, collection_tree},
library::collection::{
Collectable, Collection, CollectionId, CollectionType, DynamicCollectionRules,
},
};
impl DatabaseEntry for Collection {
type Id = CollectionId;
type EntryDb = LibraryDb;
const VERSION_NUMBER: u32 = 1;
fn tree(db: &Self::EntryDb) -> Tree {
collection_tree(db)
}
fn id(&self) -> Self::Id {
self.id
}
fn read_only(&self) -> bool {
self.read_only
}
}
#[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(),
},
}
}
pub fn with_items(mut self, items: Vec<Collectable>) -> Self {
self.collection_type = CollectionType::Static {
collectables: items,
};
self
}
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 = Infallible;
fn tx_create(
cas_tx: &mut CompareAndSwapTransaction<Self::EntryDb>,
args: Self::CreateArgs,
) -> Result<Self, CustomTransactionError<Self::Err>> {
let mut collection = Collection::new_static(args.name).map_err(|err| {
TransactionError::Database(DatabaseError::InvalidInput(err.to_string()))
})?;
if cas_tx.tx_get(collection.id())?.is_some() {
return Err(TransactionError::Database(DatabaseError::AlreadyInDatabase).into());
}
collection.items = args.collection_type;
Ok(collection)
}
}