Skip to main content

nil_core/
error.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use 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}