Skip to main content

selene_core/library/collection/
trait_impls.rs

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