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 resources")]
84 InsufficientResources,
85
86 #[error("Insufficient units")]
87 InsufficientUnits,
88
89 #[error("Expected maneuver to be pending, but it is done")]
90 ManeuverIsDone(ManeuverId),
91
92 #[error("Expected maneuver to be done, but it is pending")]
93 ManeuverIsPending(ManeuverId),
94
95 #[error("Maneuver is already returning")]
96 ManeuverIsReturning(ManeuverId),
97
98 #[error("Maneuver not found")]
99 ManeuverNotFound(ManeuverId),
100
101 #[error("No stats found for mine \"{0}\"")]
102 MineStatsNotFound(MineId),
103
104 #[error("No stats found for mine \"{0}\" at level {1}")]
105 MineStatsNotFoundForLevel(MineId, BuildingLevel),
106
107 #[error("Player \"{0}\" has already taken their turn")]
108 NotWaitingPlayer(PlayerId),
109
110 #[error("Origin and destination have the same coords")]
111 OriginIsDestination(Coord),
112
113 #[error("Player already spawned: {0}")]
114 PlayerAlreadySpawned(PlayerId),
115
116 #[error("Player not found: {0}")]
117 PlayerNotFound(PlayerId),
118
119 #[error("Precursor not found: {0}")]
120 PrecursorNotFound(PrecursorId),
121
122 #[error("Report not found")]
123 ReportNotFound(ReportId),
124
125 #[error("Cannot send resources to self")]
126 ResourceReceiverIsSender(Ruler),
127
128 #[error("Round already started")]
129 RoundAlreadyStarted,
130
131 #[error("Round has pending players")]
132 RoundHasPendingPlayers,
133
134 #[error("Round has not started yet")]
135 RoundNotStarted,
136
137 #[error("No stats found for storage \"{0}\"")]
138 StorageStatsNotFound(StorageId),
139
140 #[error("No stats found for storage \"{0}\" at level {1}")]
141 StorageStatsNotFoundForLevel(StorageId, BuildingLevel),
142
143 #[error("Too many resources")]
144 TooManyResources(Resources),
145
146 #[error("Expected \"{0}\", got \"{1}\"")]
147 UnexpectedUnit(UnitId, UnitId),
148
149 #[error("No stats found for wall at level {0}")]
150 WallStatsNotFoundForLevel(BuildingLevel),
151
152 #[error("World is full")]
153 WorldIsFull,
154}
155
156impl Serialize for Error {
157 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
158 where
159 S: Serializer,
160 {
161 serializer.serialize_str(self.to_string().as_str())
162 }
163}