screeps/enums/action_error_codes/
structurelab_error_codes.rs

1use std::{error::Error, fmt};
2
3use num_derive::FromPrimitive;
4use serde_repr::{Deserialize_repr, Serialize_repr};
5
6use crate::{constants::ErrorCode, FromReturnCode};
7
8/// Error codes used by
9/// [StructureLab::boost_creep](crate::StructureLab::boost_creep).
10///
11/// [Screeps API Docs](https://docs.screeps.com/api/#StructureLab.boostCreep).
12///
13/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/structures.js#L412)
14#[derive(
15    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
16)]
17#[repr(i8)]
18pub enum BoostCreepErrorCode {
19    NotOwner = -1,
20    NotFound = -5,
21    NotEnoughResources = -6,
22    InvalidTarget = -7,
23    NotInRange = -9,
24    RclNotEnough = -14,
25}
26
27impl FromReturnCode for BoostCreepErrorCode {
28    type Error = Self;
29
30    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
31        let maybe_result = Self::try_result_from_i8(val);
32        #[cfg(feature = "unsafe-return-conversion")]
33        unsafe {
34            maybe_result.unwrap_unchecked()
35        }
36        #[cfg(not(feature = "unsafe-return-conversion"))]
37        maybe_result.unwrap()
38    }
39
40    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
41        match val {
42            0 => Some(Ok(())),
43            -1 => Some(Err(BoostCreepErrorCode::NotOwner)),
44            -5 => Some(Err(BoostCreepErrorCode::NotFound)),
45            -6 => Some(Err(BoostCreepErrorCode::NotEnoughResources)),
46            -7 => Some(Err(BoostCreepErrorCode::InvalidTarget)),
47            -9 => Some(Err(BoostCreepErrorCode::NotInRange)),
48            -14 => Some(Err(BoostCreepErrorCode::RclNotEnough)),
49            _ => None,
50        }
51    }
52}
53
54impl fmt::Display for BoostCreepErrorCode {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        let msg: &'static str = match self {
57            BoostCreepErrorCode::NotOwner => "you are not the owner of this lab",
58            BoostCreepErrorCode::NotFound => {
59                "the mineral containing in the lab cannot boost any of the creep's body parts"
60            }
61            BoostCreepErrorCode::NotEnoughResources => {
62                "the lab does not have enough energy or minerals"
63            }
64            BoostCreepErrorCode::InvalidTarget => "the targets is not valid creep object",
65            BoostCreepErrorCode::NotInRange => "the targets are too far away",
66            BoostCreepErrorCode::RclNotEnough => {
67                "room controller level insufficient to use this structure"
68            }
69        };
70
71        write!(f, "{}", msg)
72    }
73}
74
75impl Error for BoostCreepErrorCode {}
76
77impl From<BoostCreepErrorCode> for ErrorCode {
78    fn from(value: BoostCreepErrorCode) -> Self {
79        // Safety: BoostCreepErrorCode is repr(i8), so we can cast it to get the
80        // discriminant value, which will match the raw return code value that ErrorCode
81        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
82        // Safety: BoostCreepErrorCode discriminants are always error code values, and
83        // thus the Result returned here will always be an `Err` variant, so we can
84        // always extract the error without panicking
85        Self::result_from_i8(value as i8).unwrap_err()
86    }
87}
88
89/// Error codes used by
90/// [StructureLab::reverse_reaction](crate::StructureLab::reverse_reaction).
91///
92/// [Screeps API Docs](https://docs.screeps.com/api/#StructureLab.reverseReaction).
93///
94/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/structures.js#L360)
95#[derive(
96    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
97)]
98#[repr(i8)]
99pub enum ReverseReactionErrorCode {
100    NotOwner = -1,
101    NotEnoughResources = -6,
102    InvalidTarget = -7,
103    Full = -8,
104    NotInRange = -9,
105    InvalidArgs = -10,
106    Tired = -11,
107    RclNotEnough = -14,
108}
109
110impl FromReturnCode for ReverseReactionErrorCode {
111    type Error = Self;
112
113    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
114        let maybe_result = Self::try_result_from_i8(val);
115        #[cfg(feature = "unsafe-return-conversion")]
116        unsafe {
117            maybe_result.unwrap_unchecked()
118        }
119        #[cfg(not(feature = "unsafe-return-conversion"))]
120        maybe_result.unwrap()
121    }
122
123    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
124        match val {
125            0 => Some(Ok(())),
126            -1 => Some(Err(ReverseReactionErrorCode::NotOwner)),
127            -6 => Some(Err(ReverseReactionErrorCode::NotEnoughResources)),
128            -7 => Some(Err(ReverseReactionErrorCode::InvalidTarget)),
129            -8 => Some(Err(ReverseReactionErrorCode::Full)),
130            -9 => Some(Err(ReverseReactionErrorCode::NotInRange)),
131            -10 => Some(Err(ReverseReactionErrorCode::InvalidArgs)),
132            -11 => Some(Err(ReverseReactionErrorCode::Tired)),
133            -14 => Some(Err(ReverseReactionErrorCode::RclNotEnough)),
134            _ => None,
135        }
136    }
137}
138
139impl fmt::Display for ReverseReactionErrorCode {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        let msg: &'static str = match self {
142            ReverseReactionErrorCode::NotOwner => "you are not the owner of this lab",
143            ReverseReactionErrorCode::NotEnoughResources => {
144                "the source lab do not have enough resources"
145            }
146            ReverseReactionErrorCode::InvalidTarget => "the targets are not valid lab objects",
147            ReverseReactionErrorCode::Full => "one of targets cannot receive any more resource",
148            ReverseReactionErrorCode::NotInRange => "the targets are too far away",
149            ReverseReactionErrorCode::InvalidArgs => {
150                "the reaction cannot be reversed into this resources"
151            }
152            ReverseReactionErrorCode::Tired => "the lab is still cooling down",
153            ReverseReactionErrorCode::RclNotEnough => {
154                "room controller level insufficient to use this structure"
155            }
156        };
157
158        write!(f, "{}", msg)
159    }
160}
161
162impl Error for ReverseReactionErrorCode {}
163
164impl From<ReverseReactionErrorCode> for ErrorCode {
165    fn from(value: ReverseReactionErrorCode) -> Self {
166        // Safety: ReverseReactionErrorCode is repr(i8), so we can cast it to get the
167        // discriminant value, which will match the raw return code value that ErrorCode
168        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
169        // Safety: ReverseReactionErrorCode discriminants are always error code values,
170        // and thus the Result returned here will always be an `Err` variant, so we can
171        // always extract the error without panicking
172        Self::result_from_i8(value as i8).unwrap_err()
173    }
174}
175
176/// Error codes used by
177/// [StructureLab::run_reaction](crate::StructureLab::run_reaction).
178///
179/// [Screeps API Docs](https://docs.screeps.com/api/#StructureLab.runReaction).
180///
181/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/structures.js#L317)
182#[derive(
183    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
184)]
185#[repr(i8)]
186pub enum RunReactionErrorCode {
187    NotOwner = -1,
188    NotEnoughResources = -6,
189    InvalidTarget = -7,
190    Full = -8,
191    NotInRange = -9,
192    InvalidArgs = -10,
193    Tired = -11,
194    RclNotEnough = -14,
195}
196
197impl FromReturnCode for RunReactionErrorCode {
198    type Error = Self;
199
200    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
201        let maybe_result = Self::try_result_from_i8(val);
202        #[cfg(feature = "unsafe-return-conversion")]
203        unsafe {
204            maybe_result.unwrap_unchecked()
205        }
206        #[cfg(not(feature = "unsafe-return-conversion"))]
207        maybe_result.unwrap()
208    }
209
210    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
211        match val {
212            0 => Some(Ok(())),
213            -1 => Some(Err(RunReactionErrorCode::NotOwner)),
214            -6 => Some(Err(RunReactionErrorCode::NotEnoughResources)),
215            -7 => Some(Err(RunReactionErrorCode::InvalidTarget)),
216            -8 => Some(Err(RunReactionErrorCode::Full)),
217            -9 => Some(Err(RunReactionErrorCode::NotInRange)),
218            -10 => Some(Err(RunReactionErrorCode::InvalidArgs)),
219            -11 => Some(Err(RunReactionErrorCode::Tired)),
220            -14 => Some(Err(RunReactionErrorCode::RclNotEnough)),
221            _ => None,
222        }
223    }
224}
225
226impl fmt::Display for RunReactionErrorCode {
227    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228        let msg: &'static str = match self {
229            RunReactionErrorCode::NotOwner => "you are not the owner of this lab",
230            RunReactionErrorCode::NotEnoughResources => {
231                "the source lab do not have enough resources"
232            }
233            RunReactionErrorCode::InvalidTarget => "the targets are not valid lab objects",
234            RunReactionErrorCode::Full => "the target cannot receive any more resource",
235            RunReactionErrorCode::NotInRange => "the targets are too far away",
236            RunReactionErrorCode::InvalidArgs => "the reaction cannot be run using this resources",
237            RunReactionErrorCode::Tired => "the lab is still cooling down",
238            RunReactionErrorCode::RclNotEnough => {
239                "room controller level insufficient to use this structure"
240            }
241        };
242
243        write!(f, "{}", msg)
244    }
245}
246
247impl Error for RunReactionErrorCode {}
248
249impl From<RunReactionErrorCode> for ErrorCode {
250    fn from(value: RunReactionErrorCode) -> Self {
251        // Safety: RunReactionErrorCode is repr(i8), so we can cast it to get the
252        // discriminant value, which will match the raw return code value that ErrorCode
253        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
254        // Safety: RunReactionErrorCode discriminants are always error code values, and
255        // thus the Result returned here will always be an `Err` variant, so we can
256        // always extract the error without panicking
257        Self::result_from_i8(value as i8).unwrap_err()
258    }
259}
260
261/// Error codes used by
262/// [StructureLab::unboost_creep](crate::StructureLab::unboost_creep).
263///
264/// [Screeps API Docs](https://docs.screeps.com/api/#StructureLab.unboostCreep).
265///
266/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/structures.js#L443)
267#[derive(
268    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
269)]
270#[repr(i8)]
271pub enum UnboostCreepErrorCode {
272    NotOwner = -1,
273    NotFound = -5,
274    InvalidTarget = -7,
275    NotInRange = -9,
276    Tired = -11,
277    RclNotEnough = -14,
278}
279
280impl FromReturnCode for UnboostCreepErrorCode {
281    type Error = Self;
282
283    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
284        let maybe_result = Self::try_result_from_i8(val);
285        #[cfg(feature = "unsafe-return-conversion")]
286        unsafe {
287            maybe_result.unwrap_unchecked()
288        }
289        #[cfg(not(feature = "unsafe-return-conversion"))]
290        maybe_result.unwrap()
291    }
292
293    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
294        match val {
295            0 => Some(Ok(())),
296            -1 => Some(Err(UnboostCreepErrorCode::NotOwner)),
297            -5 => Some(Err(UnboostCreepErrorCode::NotFound)),
298            -7 => Some(Err(UnboostCreepErrorCode::InvalidTarget)),
299            -9 => Some(Err(UnboostCreepErrorCode::NotInRange)),
300            -11 => Some(Err(UnboostCreepErrorCode::Tired)),
301            -14 => Some(Err(UnboostCreepErrorCode::RclNotEnough)),
302            _ => None,
303        }
304    }
305}
306
307impl fmt::Display for UnboostCreepErrorCode {
308    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309        let msg: &'static str = match self {
310            UnboostCreepErrorCode::NotOwner => {
311                "you are not the owner of this lab, or the target creep"
312            }
313            UnboostCreepErrorCode::NotFound => "the target has no boosted parts",
314            UnboostCreepErrorCode::InvalidTarget => "the target is not a valid creep object",
315            UnboostCreepErrorCode::NotInRange => "the target is too far away",
316            UnboostCreepErrorCode::Tired => "the lab is still cooling down",
317            UnboostCreepErrorCode::RclNotEnough => {
318                "room controller level insufficient to use this structure"
319            }
320        };
321
322        write!(f, "{}", msg)
323    }
324}
325
326impl Error for UnboostCreepErrorCode {}
327
328impl From<UnboostCreepErrorCode> for ErrorCode {
329    fn from(value: UnboostCreepErrorCode) -> Self {
330        // Safety: UnboostCreepErrorCode is repr(i8), so we can cast it to get the
331        // discriminant value, which will match the raw return code value that ErrorCode
332        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
333        // Safety: UnboostCreepErrorCode discriminants are always error code values, and
334        // thus the Result returned here will always be an `Err` variant, so we can
335        // always extract the error without panicking
336        Self::result_from_i8(value as i8).unwrap_err()
337    }
338}