Skip to main content

manabrew_engine/card/
card_collection.rs

1use crate::ids::CardId;
2
3use super::card_collection_view::CardCollectionView;
4
5/// Card id collection utility mirroring Java's `CardCollection`.
6#[derive(Debug, Clone, Default, PartialEq, Eq)]
7pub struct CardCollection {
8    cards: Vec<CardId>,
9}
10
11impl CardCollection {
12    pub const EMPTY: Self = Self { cards: Vec::new() };
13
14    pub fn new() -> Self {
15        Self { cards: Vec::new() }
16    }
17
18    pub fn push(&mut self, card: CardId) {
19        self.cards.push(card);
20    }
21
22    pub fn extend<I: IntoIterator<Item = CardId>>(&mut self, iter: I) {
23        self.cards.extend(iter);
24    }
25
26    pub fn iter(&self) -> impl Iterator<Item = &CardId> {
27        self.cards.iter()
28    }
29
30    /// Combine multiple views preserving their view order and card order.
31    pub fn combine(views: &[&dyn CardCollectionView]) -> CardCollection {
32        let mut out = CardCollection::new();
33        for v in views {
34            if v.is_empty() {
35                continue;
36            }
37            out.extend(v.as_slice().iter().copied());
38        }
39        out
40    }
41
42    /// Return a shallow-copy sub-list in `[from_index, to_index)`.
43    pub fn sub_list(&self, from_index: usize, to_index: usize) -> CardCollection {
44        let end = to_index.min(self.cards.len());
45        let start = from_index.min(end);
46        CardCollection::from_iter(self.cards[start..end].iter().copied())
47    }
48
49    /// Return a filtered copy of this collection.
50    pub fn filter<F>(&self, test: F) -> CardCollection
51    where
52        F: Fn(&CardId) -> bool,
53    {
54        CardCollection::from_iter(self.cards.iter().copied().filter(test))
55    }
56}
57
58impl FromIterator<CardId> for CardCollection {
59    fn from_iter<I: IntoIterator<Item = CardId>>(iter: I) -> Self {
60        Self {
61            cards: iter.into_iter().collect(),
62        }
63    }
64}
65
66impl CardCollectionView for CardCollection {
67    fn is_empty(&self) -> bool {
68        self.cards.is_empty()
69    }
70
71    fn len(&self) -> usize {
72        self.cards.len()
73    }
74
75    fn as_slice(&self) -> &[CardId] {
76        &self.cards
77    }
78}