use core::card::*;
use std::ops::Index;
use std::ops::{RangeFull, RangeTo, RangeFrom};
use std::slice::Iter;
use std::collections::HashSet;
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Hand {
cards: Vec<Card>,
}
impl Hand {
pub fn default() -> Hand {
Hand { cards: Vec::with_capacity(5) }
}
pub fn new_with_cards(cards: Vec<Card>) -> Hand {
Hand { cards: cards }
}
pub fn new_from_str(hand_string: &str) -> Result<Hand, String> {
let mut chars = hand_string.chars();
let mut cards: HashSet<Card> = HashSet::with_capacity(7);
loop {
let vco = chars.next();
if vco == None {
break;
} else {
let sco = chars.next();
let v = try!(vco.and_then(Value::from_char)
.ok_or_else(|| {
format!("Couldn't parse value {}",
vco.unwrap_or('?'))
}));
let s = try!(sco.and_then(Suit::from_char)
.ok_or_else(|| {
format!("Couldn't parse suit {}",
sco.unwrap_or('?'))
}));
let c = Card { value: v, suit: s };
if !cards.insert(c) {
return Err(format!("This card has already been added {}", c));
}
}
}
if chars.next() != None {
return Err(String::from("Extra un-used chars found."));
}
let mut cv: Vec<Card> = cards.into_iter().collect();
cv.reserve(7);
Ok(Hand { cards: cv })
}
pub fn push(&mut self, c: Card) {
self.cards.push(c);
}
pub fn truncate(&mut self, len: usize) {
self.cards.truncate(len)
}
pub fn len(&self) -> usize {
self.cards.len()
}
pub fn is_empty(&self) -> bool {
self.cards.is_empty()
}
pub fn iter(&self) -> Iter<Card> {
self.cards.iter()
}
}
impl Index<usize> for Hand {
type Output = Card;
fn index(&self, index: usize) -> &Card {
&self.cards[index]
}
}
impl Index<RangeFull> for Hand {
type Output = [Card];
fn index(&self, range: RangeFull) -> &[Card] {
&self.cards[range]
}
}
impl Index<RangeTo<usize>> for Hand {
type Output = [Card];
fn index(&self, index: RangeTo<usize>) -> &[Card] {
&self.cards[index]
}
}
impl Index<RangeFrom<usize>> for Hand {
type Output = [Card];
fn index(&self, index: RangeFrom<usize>) -> &[Card] {
&self.cards[index]
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::card::Card;
#[test]
fn test_add_card() {
assert!(true);
let mut h = Hand::default();
let c = Card {
value: Value::Three,
suit: Suit::Spade,
};
h.push(c);
assert_eq!(1, h.len());
}
#[test]
fn test_index() {
let mut h = Hand::default();
h.push(Card {
value: Value::Four,
suit: Suit::Spade,
});
assert_eq!(Card {
value: Value::Four,
suit: Suit::Spade,
},
h[0]);
}
#[test]
fn test_parse_error() {
assert!(Hand::new_from_str("BAD").is_err());
assert!(Hand::new_from_str("Adx").is_err());
}
#[test]
fn test_parse_one_hand() {
let h = Hand::new_from_str("Ad").unwrap();
assert_eq!(1, h.len())
}
#[test]
fn test_parse_empty() {
let h = Hand::new_from_str("").unwrap();
assert!(h.is_empty());
}
}