speki_core/
collection.rs

1use std::{cmp::Ordering, sync::Arc};
2
3use ledgerstore::{PropertyCache, TheCacheGetter};
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    card::{CType, CardId},
8    card_provider::CardProvider,
9    Card, CardProperty, CardRefType,
10};
11
12#[derive(Debug, Clone, Eq, PartialEq)]
13pub enum MaybeCard {
14    Id(CardId),
15    Card(Arc<Card>),
16}
17
18impl MaybeCard {
19    pub fn id(&self) -> CardId {
20        match self {
21            Self::Id(id) => *id,
22            Self::Card(ref card) => card.id(),
23        }
24    }
25}
26
27impl Ord for MaybeCard {
28    fn cmp(&self, other: &Self) -> Ordering {
29        self.id().cmp(&other.id())
30    }
31}
32
33impl PartialOrd for MaybeCard {
34    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
35        Some(self.cmp(other))
36    }
37}
38
39#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Copy, Hash, PartialOrd, Ord)]
40pub enum DynCard {
41    Instances(CardId),
42    Dependents(CardId),
43    RecDependents(CardId),
44    CardType(CType),
45    Trivial(bool),
46}
47
48impl DynCard {
49    pub fn display(&self, provider: CardProvider) -> String {
50        let name = |id: &CardId| {
51            provider
52                .load(*id)
53                .map(|card| card.name().to_string())
54                .unwrap_or("<invalid card>".to_string())
55        };
56
57        match self {
58            DynCard::Trivial(flag) => format!("trivial: {}", flag),
59            DynCard::Instances(id) => format!("instances: {}", name(id)),
60            DynCard::Dependents(id) => format!("dependents: {}", name(id)),
61            DynCard::RecDependents(id) => format!("dependents: {}", name(id)),
62            DynCard::CardType(ctype) => {
63                format!("card type: {ctype}")
64            }
65        }
66    }
67
68    pub fn evaluate(&self, provider: CardProvider) -> Vec<MaybeCard> {
69        match self {
70            DynCard::Instances(id) => {
71                let mut output = vec![];
72                let getter = ledgerstore::TheCacheGetter::ItemRef {
73                    reversed: false,
74                    key: *id,
75                    ty: Some(CardRefType::ParentClass),
76                    recursive: true,
77                };
78                let mut all_classes = dbg!(provider.providers.cards.load_getter(getter));
79                all_classes.insert(*id);
80
81                for class in all_classes {
82                    let getter = TheCacheGetter::ItemRef {
83                        reversed: true,
84                        key: class,
85                        ty: Some(CardRefType::ClassOfInstance),
86                        recursive: false,
87                    };
88                    for instance in provider.providers.cards.load_getter(getter) {
89                        output.push(MaybeCard::Id(instance));
90                    }
91                }
92
93                output
94            }
95            DynCard::Trivial(flag) => provider
96                .providers
97                .cards
98                .get_prop_cache(PropertyCache::new(CardProperty::Trivial, flag.to_string()))
99                .into_iter()
100                .map(|id| MaybeCard::Id(id))
101                .collect(),
102            DynCard::CardType(ty) => provider
103                .providers
104                .cards
105                .get_prop_cache(PropertyCache::new(CardProperty::CardType, ty.to_string()))
106                .into_iter()
107                .map(|id| MaybeCard::Id(id))
108                .collect(),
109
110            DynCard::Dependents(id) => match provider.load(*id) {
111                Some(card) => card.dependents().into_iter().map(MaybeCard::Card).collect(),
112                None => vec![],
113            },
114
115            DynCard::RecDependents(id) => {
116                dbg!("rec dependents");
117                let ids = match dbg!(provider.load(*id)) {
118                    Some(x) => x.recursive_dependents(),
119                    None => return vec![],
120                };
121
122                let mut out = vec![];
123
124                for (idx, id) in ids.into_iter().enumerate() {
125                    if idx % 50 == 0 {
126                        dbg!(idx);
127                    }
128
129                    out.push(MaybeCard::Id(id));
130                }
131                dbg!();
132
133                out
134            }
135        }
136    }
137}