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 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}