crabchess 0.1.15

A simple Chess API
Documentation
use crate::prelude::{Color, Move, Side, Square, Timer, Type};
use anyhow::Error;
use smallvec::SmallVec;

#[derive(thiserror::Error, Debug)]
pub enum Err {
    #[error("Could not read {0} in FEN '{1}'.")]
    FenParsingError(&'static str, String),

    #[error("Invalid {0} in FEN '{1}'.")]
    InvalidFenError(&'static str, String),

    #[error(
        "Only rooks with annotated sides and kings are tracked in `CastlingRights`. \
        Got `pt = {0:?}`, `side = {1:?}`."
    )]
    CastlingRightsError(Type, Option<Side>),

    #[error("Expected 1 {0} King, got {1}.")]
    KingCountError(Color, usize),

    #[error("Squares {0} and {1} are not inline.")]
    SquaresNotInlineError(Square, Square),

    #[error("Cannot convert {0} to {1}.")]
    ConversionError(&'static str, &'static str),

    #[error("Timers have already been set.")]
    TimersAlreadySetError,

    #[error("{} is not a valid en passant final square.", .0)]
    EnPassantRankError(Square),

    #[error("The position is invalid because {0} king is in check and not up to move.")]
    PlayerCanCaptureKingError(Color),

    #[error("FEN cannot be empty.")]
    EmptyFenError,

    #[error("FEN ('{0}') is missing {1}.")]
    FenMissingFieldError(String, &'static str),

    #[error("Move '{0}' is illegal: `{1}`.")]
    IllegalSanError(String, String),

    #[error("Error \"{1}\" applying move: {0:?}.")]
    ApplyMoveError(Move, String),

    #[error("Position does not have move history.")]
    NoMoveHistoryError,

    #[error("Failed to parse movetext.")]
    MovetextParseError,

    #[error("Expected move number indicator preceding clock annotation.")]
    MissingMoveNumberIndicatorError,

    #[error("Failed to export position to FEN: {0}.")]
    FailedFenExportError(Error),

    #[error("`InitialPosition::Unspecified` cannot be exported to FEN.")]
    UnspecifiedFenExportAttemptError,

    #[error("Initial position is necessary to export PGN.")]
    MissingInitialPositionError,

    #[error("SAN string cannot be empty.")]
    EmptySanError,

    #[error("{0} is not a `LinearPieceType`.")]
    LinearPieceTypeError(Type),

    #[error("Pawns cannot be promoted to {0}.")]
    PromotedTypeError(Type),

    #[error("Could not read move annotation '{0}'.")]
    MoveAnnotationParseError(String),

    #[error("File char '{0}' is not in 'ABCDEFGH'.")]
    InvalidFileCharError(char),

    #[error("'{0}' is not a valid rank index.")]
    RankFromIndexError(i8),

    #[error(
        "Rank character must be an ASCII digit between 1 and 8 (inclusive), \
        got '{0}'."
    )]
    RankFromCharError(char),

    #[error("Cannot determine direction between squares because both are equal to {0}.")]
    EqualSquaresError(Square),

    #[error("Square string '{0}' is missing file character.")]
    MissingFileCharError(String),

    #[error("Square string '{0}' is missing rank character.")]
    MissingRankCharError(String),

    #[error("Notation '{0}' does not indicate a final square.")]
    MissingFinalSquareError(String),

    #[error("Invalid FEN piece indicator '{0}'. Can only parse characters in 'KQRBNPkqrbnp'.")]
    InvalidPieceIndicatorError(char),

    #[error("White and Black have different time controls.\nWhite: {0:?}\nBlack: {1:?}")]
    DifferentTimeControlsError(Timer, Timer),

    #[error("Could not parse `{0}`: '{1}'.")]
    ParseError(&'static str, String),

    #[error("PGN marker must contain at least one period. Failed to read '{0}'.")]
    PgnMarkerMissingPeriodError(String),

    #[error("Error reading SAN '{0}': \"{1}\".")]
    ReadSanError(String, &'static str),

    #[error("Move '{0}' needs a disambiguator to distinguish between possible moves: {1:?}.")]
    NeedsDisambiguatorError(String, Box<SmallVec<[Move; 8]>>),

    #[error("Expected a piece at square {0}.")]
    MissingPieceError(Square),

    #[error("No suitable candidates for {0} move from {1} to {2}.")]
    NoSuitableCandidatesError(Type, Square, Square),

    #[error("Expected a `Move::Castle`, got `{0:?}`.")]
    ExpectedCastleError(Move),

    #[error("Failed to determine rook initial squares.")]
    UnknownRookInitialSquares,

    #[error("PositionBuilder is missing `{0}` field.")]
    MissingPositionField(&'static str),

    #[error("PGN is missing result indicator at end of movetext.")]
    MissingResultError,

    #[error("Failed to read \"{0}\".")]
    FileReadError(&'static str),
}

pub type Result<T> = std::result::Result<T, Err>;