1use crate::continent::coord::Coord;
5use crate::continent::index::ContinentIndex;
6use crate::infrastructure::building::level::BuildingLevel;
7use crate::infrastructure::building::{BuildingId, MineId, StorageId};
8use crate::military::army::ArmyId;
9use crate::military::maneuver::ManeuverId;
10use crate::military::unit::UnitId;
11use crate::npc::bot::BotId;
12use crate::npc::precursor::PrecursorId;
13use crate::player::PlayerId;
14use crate::report::ReportId;
15use serde::Serialize;
16use serde::ser::Serializer;
17use std::result::Result as StdResult;
18use strum::EnumIs;
19
20pub type Result<T, E = Error> = StdResult<T, E>;
21pub type AnyResult<T> = anyhow::Result<T>;
22
23#[derive(Clone, Debug, EnumIs, thiserror::Error)]
24#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
25#[cfg_attr(feature = "typescript", ts(as = "String"))]
26#[remain::sorted]
27pub enum Error {
28 #[error("Army not found")]
29 ArmyNotFound(ArmyId),
30
31 #[error("Army is not idle")]
32 ArmyNotIdle(ArmyId),
33
34 #[error("Bot already spawned: {0}")]
35 BotAlreadySpawned(BotId),
36
37 #[error("Bot not found: {0}")]
38 BotNotFound(BotId),
39
40 #[error("No stats found for building \"{0}\"")]
41 BuildingStatsNotFound(BuildingId),
42
43 #[error("No stats found for building \"{0}\" at level {1}")]
44 BuildingStatsNotFoundForLevel(BuildingId, BuildingLevel),
45
46 #[error("Building \"{0}\" is already at its minimum level")]
47 CannotDecreaseBuildingLevel(BuildingId),
48
49 #[error("Building \"{0}\" is already at its maximum level")]
50 CannotIncreaseBuildingLevel(BuildingId),
51
52 #[error("Cheating is not allowed in this world")]
53 CheatingNotAllowed,
54
55 #[error("City not found: {0}")]
56 CityNotFound(Coord),
57
58 #[error("Failed to deserialize event")]
59 FailedToDeserializeEvent,
60
61 #[error("Failed to read savedata file")]
62 FailedToReadSavedata,
63
64 #[error("Failed to serialize event")]
65 FailedToSerializeEvent,
66
67 #[error("Failed to write savedata file")]
68 FailedToWriteSavedata,
69
70 #[error("Not authorized to execute this action")]
71 Forbidden,
72
73 #[error("Index out of bounds: {0}")]
74 IndexOutOfBounds(ContinentIndex),
75
76 #[error("Insufficient resources")]
77 InsufficientResources,
78
79 #[error("Insufficient units")]
80 InsufficientUnits,
81
82 #[error("Expected maneuver to be pending, but it is done")]
83 ManeuverIsDone(ManeuverId),
84
85 #[error("Expected maneuver to be done, but it is pending")]
86 ManeuverIsPending(ManeuverId),
87
88 #[error("Maneuver is already returning")]
89 ManeuverIsReturning(ManeuverId),
90
91 #[error("Maneuver not found")]
92 ManeuverNotFound(ManeuverId),
93
94 #[error("No stats found for mine \"{0}\"")]
95 MineStatsNotFound(MineId),
96
97 #[error("No stats found for mine \"{0}\" at level {1}")]
98 MineStatsNotFoundForLevel(MineId, BuildingLevel),
99
100 #[error("No players in the world")]
101 NoPlayer,
102
103 #[error("Player \"{0}\" has already taken their turn")]
104 NotWaitingPlayer(PlayerId),
105
106 #[error("Origin and destination have the same coords")]
107 OriginIsDestination(Coord),
108
109 #[error("Player already spawned: {0}")]
110 PlayerAlreadySpawned(PlayerId),
111
112 #[error("Player not found: {0}")]
113 PlayerNotFound(PlayerId),
114
115 #[error("Precursor not found: {0}")]
116 PrecursorNotFound(PrecursorId),
117
118 #[error("Report not found")]
119 ReportNotFound(ReportId),
120
121 #[error("Round already started")]
122 RoundAlreadyStarted,
123
124 #[error("Round has pending players")]
125 RoundHasPendingPlayers,
126
127 #[error("Round has not started yet")]
128 RoundNotStarted,
129
130 #[error("No stats found for storage \"{0}\"")]
131 StorageStatsNotFound(StorageId),
132
133 #[error("No stats found for storage \"{0}\" at level {1}")]
134 StorageStatsNotFoundForLevel(StorageId, BuildingLevel),
135
136 #[error("Expected \"{0}\", got \"{1}\"")]
137 UnexpectedUnit(UnitId, UnitId),
138
139 #[error("No stats found for wall at level {0}")]
140 WallStatsNotFoundForLevel(BuildingLevel),
141
142 #[error("World is full")]
143 WorldIsFull,
144}
145
146impl Serialize for Error {
147 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
148 where
149 S: Serializer,
150 {
151 serializer.serialize_str(self.to_string().as_str())
152 }
153}