Skip to main content

selene_core/library/collection/
trait_impls.rs

1use lunar_lib::database::{
2    CompareAndSwapTransaction, Createable, CustomTransactionError, DatabaseEntry, TransactionError,
3    caching::Cacheable,
4};
5
6use crate::{
7    database::{COLLECTION_CACHE, LibraryDb},
8    library::{
9        collectable::Collectable,
10        collection::{
11            Collection, CollectionCreationError, CollectionId, CollectionType,
12            DynamicCollectionRules,
13        },
14    },
15};
16
17impl DatabaseEntry for Collection {
18    type Id = CollectionId;
19    type Db = LibraryDb;
20
21    const VERSION_NUMBER: u32 = 1;
22    const TREE_NAME: &str = "collection";
23
24    fn id(&self) -> Self::Id {
25        self.id
26    }
27
28    fn read_only(&self) -> bool {
29        self.read_only
30    }
31}
32
33impl Cacheable for Collection {
34    fn cache() -> &'static std::sync::Mutex<lunar_lib::database::caching::DbCache<Self>> {
35        &COLLECTION_CACHE
36    }
37}
38
39#[derive(Debug, Clone)]
40pub struct CollectionCreateArgs {
41    name: String,
42    collection_type: CollectionType,
43}
44
45impl CollectionCreateArgs {
46    pub fn new(name: impl Into<String>) -> Self {
47        Self {
48            name: name.into(),
49            collection_type: CollectionType::Static {
50                collectables: Vec::new(),
51            },
52        }
53    }
54
55    #[must_use]
56    pub fn with_items(mut self, items: Vec<Collectable>) -> Self {
57        self.collection_type = CollectionType::Static {
58            collectables: items,
59        };
60        self
61    }
62
63    #[must_use]
64    pub fn with_rules(mut self, rules: Vec<DynamicCollectionRules>) -> Self {
65        self.collection_type = CollectionType::Dynamic { rules };
66        self
67    }
68}
69
70impl Createable for Collection {
71    type CreateArgs = CollectionCreateArgs;
72    type Err = CollectionCreationError;
73
74    fn tx_create(
75        cas_tx: &mut CompareAndSwapTransaction<Self::Db>,
76        args: Self::CreateArgs,
77    ) -> Result<Self, CustomTransactionError<Self::Err>> {
78        let mut collection =
79            Collection::new_static(args.name).map_err(CustomTransactionError::Closure)?;
80
81        if cas_tx.tx_get(collection.id())?.is_some() {
82            return Err(TransactionError::AlreadyInDatabase.into());
83        }
84
85        collection.items = args.collection_type;
86
87        Ok(collection)
88    }
89}