use crate::continent::{ContinentIndex, Coord};
use crate::infrastructure::building::level::BuildingLevel;
use crate::infrastructure::building::{BuildingId, MineId, StorageId};
use crate::military::army::ArmyId;
use crate::military::maneuver::ManeuverId;
use crate::military::unit::UnitId;
use crate::npc::bot::BotId;
use crate::npc::precursor::PrecursorId;
use crate::player::PlayerId;
use crate::report::ReportId;
use serde::Serialize;
use serde::ser::Serializer;
use std::result::Result as StdResult;
use strum::EnumIs;
pub type Result<T, E = Error> = StdResult<T, E>;
pub type AnyResult<T> = anyhow::Result<T>;
#[derive(Clone, Debug, EnumIs, thiserror::Error)]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
#[cfg_attr(feature = "typescript", ts(as = "String"))]
#[remain::sorted]
pub enum Error {
#[error("Army not found")]
ArmyNotFound(ArmyId),
#[error("Army is not idle")]
ArmyNotIdle(ArmyId),
#[error("Bot already spawned: {0}")]
BotAlreadySpawned(BotId),
#[error("Bot not found: {0}")]
BotNotFound(BotId),
#[error("No stats found for building \"{0}\"")]
BuildingStatsNotFound(BuildingId),
#[error("No stats found for building \"{0}\" at level {1}")]
BuildingStatsNotFoundForLevel(BuildingId, BuildingLevel),
#[error("Building \"{0}\" is already at its minimum level")]
CannotDecreaseBuildingLevel(BuildingId),
#[error("Building \"{0}\" is already at its maximum level")]
CannotIncreaseBuildingLevel(BuildingId),
#[error("Cheating is not allowed in this world")]
CheatingNotAllowed,
#[error("City not found: {0}")]
CityNotFound(Coord),
#[error("Failed to deserialize event")]
FailedToDeserializeEvent,
#[error("Failed to read savedata file")]
FailedToReadSavedata,
#[error("Failed to serialize event")]
FailedToSerializeEvent,
#[error("Failed to write savedata file")]
FailedToWriteSavedata,
#[error("Not authorized to execute this action")]
Forbidden,
#[error("Index out of bounds: {0}")]
IndexOutOfBounds(ContinentIndex),
#[error("Insufficient resources")]
InsufficientResources,
#[error("Insufficient units")]
InsufficientUnits,
#[error("Expected maneuver to be pending, but it is done")]
ManeuverIsDone(ManeuverId),
#[error("Expected maneuver to be done, but it is pending")]
ManeuverIsPending(ManeuverId),
#[error("Maneuver is already returning")]
ManeuverIsReturning(ManeuverId),
#[error("Maneuver not found")]
ManeuverNotFound(ManeuverId),
#[error("No stats found for mine \"{0}\"")]
MineStatsNotFound(MineId),
#[error("No stats found for mine \"{0}\" at level {1}")]
MineStatsNotFoundForLevel(MineId, BuildingLevel),
#[error("No players in the world")]
NoPlayer,
#[error("Player \"{0}\" has already taken their turn")]
NotWaitingPlayer(PlayerId),
#[error("Origin and destination have the same coords")]
OriginIsDestination(Coord),
#[error("Player already spawned: {0}")]
PlayerAlreadySpawned(PlayerId),
#[error("Player not found: {0}")]
PlayerNotFound(PlayerId),
#[error("Precursor not found: {0}")]
PrecursorNotFound(PrecursorId),
#[error("Report not found")]
ReportNotFound(ReportId),
#[error("Round already started")]
RoundAlreadyStarted,
#[error("Round has pending players")]
RoundHasPendingPlayers,
#[error("Round has not started yet")]
RoundNotStarted,
#[error("No stats found for storage \"{0}\"")]
StorageStatsNotFound(StorageId),
#[error("No stats found for storage \"{0}\" at level {1}")]
StorageStatsNotFoundForLevel(StorageId, BuildingLevel),
#[error("Expected \"{0}\", got \"{1}\"")]
UnexpectedUnit(UnitId, UnitId),
#[error("No stats found for wall at level {0}")]
WallStatsNotFoundForLevel(BuildingLevel),
#[error("World is full")]
WorldIsFull,
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_str())
}
}