Comments. Lot of Comments.
/// Implementation of a Row of Cards on the Table (max 5)
// We use std::mem::take to do tricks with vector members and ownership.
use std::{collections::VecDeque, mem};
use crate::card::Card;
#[derive(Debug)]
/// A `Row` of [`Card`]s, in a two-ended vector (`VecDeque`).
/// A Row is smart and can do a few things on herself.
pub(crate) struct Row {
cards: VecDeque<Card>,
}
impl Row {
/// The maximum length of a Row. More cards cause overflow and force collection.
const MAX_LEN: usize = 5;
/// Create a new [`Row`] with capacity of 5 [`Card`]s.
pub(crate) fn new() -> Self {
Row {
cards: VecDeque::with_capacity(5),
}
}
/// Push a [`Card`] to the end of the Row.
/// If it would make Row over maximum length the function
/// returns the content of the row, and then push the new
/// Card as the new Row head.
/// Otherwise return None.
/// # Arguments
/// - [`Card`] - the new card to put into the Row
/// # Returns
/// - `Option<VecDequeue<Card>>` - None or Some(cards) to be collected from Row
pub(crate) fn push_or_collect( &mut self, card: Card ) -> Option<VecDeque<Card>> {
trace!("Called push_or_collect on row {:?}", &self);
if self.cards.len() < Self::MAX_LEN {
trace!("Less than {} cards, putting at the end", Self::MAX_LEN);
self.cards.push_back(card);
None
} else {
trace!("Row is full, len {}, maxlen {}", self.cards.len(), Self::MAX_LEN);
// Row overflow. We take out `cards` from `self` with its ownership and
// leave the default (empty VecDeque) in its place, without disturbing
// `self` ownership.
let row_cards = mem::take( &mut self.cards );
// We put new card as new Row head.
self.cards.push_back(card);
if self.cards.len() != 1 {
panic!("New row must have one card, not {}", self.cards.len());
}
// Return the collected old Row content
Some(row_cards)
}
}
/// Take out all `cards` (and their ownership) and return them.
pub(crate) fn take_row( &mut self ) -> VecDeque<Card> {
// take cards and empty the row
mem::take( &mut self.cards )
}
/// Return the `value` of the last card in the Row.
/// This is the largest value since the Row is always ordered.
pub(crate) fn last_card_value(&self) -> i8 {
// println!("last_card_value: cards {:?}, len {}", self.cards, self.cards.len());
self.cards.get( self.cards.len()-1 ).unwrap().value
}
// sum of row card points
pub(crate) fn sum(&self) -> i32 {
let mut sum: i32 = 0;
self.cards.iter().for_each(|card| {
sum += card.points as i32;
});
sum
}
#[allow(dead_code)]
/// We could use this, but... borrow checker, you know. Needs more love.
/// I could have used `_len` to shut up the dead_code warning, so this is
/// another example to do it the other way.
pub fn len(&self) -> usize {
self.cards.len()
}
}