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