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}