use core::fmt::{self, Write};
use core::str;
use prelude::*;
use board::PieceMap;
#[derive(Clone, PartialEq, Eq)]
pub struct Fen {
pub pieces: PieceMap,
pub color: Color,
pub castling: Rights,
pub en_passant: Option<Square>,
pub halfmoves: u32,
pub fullmoves: u32,
}
impl fmt::Display for Fen {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.pieces.map_fen(|s| f.write_str(s))?;
{
let mut buf: [u8; 4] = *b" ";
buf[1] = match self.color {
Color::White => b'w',
Color::Black => b'b',
};
let string = unsafe { str::from_utf8_unchecked(&buf[..3]) };
f.write_str(string)?;
}
self.castling.map_str(|s| f.write_str(s))?;
if let Some(sq) = self.en_passant {
let mut buf: [u8; 4] = *b" ";
buf[1] = char::from(sq.file()) as u8;
buf[2] = char::from(sq.rank()) as u8;
let string = unsafe { str::from_utf8_unchecked(&buf) };
f.write_str(string)?;
} else {
f.write_str(" - ")?;
}
self.halfmoves.fmt(f)?;
f.write_char(' ')?;
self.fullmoves.fmt(f)
}
}
impl Fen {
pub const STARTING: Fen = Fen {
pieces: PieceMap::STANDARD,
color: Color::White,
castling: Rights::FULL,
en_passant: None,
halfmoves: 0,
fullmoves: 1,
};
pub const EMPTY: Fen = Fen {
pieces: PieceMap::EMPTY,
color: Color::White,
castling: Rights::EMPTY,
en_passant: None,
halfmoves: 0,
fullmoves: 1,
};
}
#[cfg(test)]
#[cfg(feature = "std")]
mod tests {
use super::*;
#[test]
fn display() {
let fens = [
(Fen::STARTING, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"),
(Fen::EMPTY, "8/8/8/8/8/8/8/8 w - - 0 1"),
];
for &(ref fen, exp) in fens.iter() {
let string = format!("{}", fen);
assert_eq!(string, exp);
}
}
}