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