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>;