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