Skip to main content

screeps/enums/action_error_codes/
creep_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 [Creep::claim_reactor](crate::Creep::claim_reactor).
9///
10/// [Screeps API Docs](https://docs-season.screeps.com/api/#Creep.claimReactor).
11///
12/// [Screeps Engine Source Code](https://github.com/screeps/mod-season5/blob/master/src/creep.claimReactor.js#L14)
13#[cfg(feature = "seasonal-season-5")]
14#[derive(
15    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
16)]
17#[repr(i8)]
18pub enum CreepClaimReactorErrorCode {
19    NotOwner = -1,
20    Busy = -4,
21    InvalidTarget = -7,
22    NotInRange = -9,
23    NoBodypart = -12,
24}
25
26#[cfg(feature = "seasonal-season-5")]
27impl FromReturnCode for CreepClaimReactorErrorCode {
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(CreepClaimReactorErrorCode::NotOwner)),
44            -4 => Some(Err(CreepClaimReactorErrorCode::Busy)),
45            -7 => Some(Err(CreepClaimReactorErrorCode::InvalidTarget)),
46            -9 => Some(Err(CreepClaimReactorErrorCode::NotInRange)),
47            -12 => Some(Err(CreepClaimReactorErrorCode::NoBodypart)),
48            _ => None,
49        }
50    }
51}
52
53#[cfg(feature = "seasonal-season-5")]
54impl fmt::Display for CreepClaimReactorErrorCode {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        let msg: &'static str = match self {
57            CreepClaimReactorErrorCode::NotOwner => "you are not the owner of this creep",
58            CreepClaimReactorErrorCode::Busy => "the creep is still being spawned",
59            CreepClaimReactorErrorCode::InvalidTarget => "the target is not a reactor",
60            CreepClaimReactorErrorCode::NotInRange => "the target is too far away",
61            CreepClaimReactorErrorCode::NoBodypart => {
62                "there are no claim body parts in this creep’s body"
63            }
64        };
65
66        write!(f, "{}", msg)
67    }
68}
69
70#[cfg(feature = "seasonal-season-5")]
71impl Error for CreepClaimReactorErrorCode {}
72
73#[cfg(feature = "seasonal-season-5")]
74impl From<CreepClaimReactorErrorCode> for ErrorCode {
75    fn from(value: CreepClaimReactorErrorCode) -> Self {
76        // Safety: CreepClaimReactorErrorCode is repr(i8), so we can cast it to get the
77        // discriminant value, which will match the raw return code value that ErrorCode
78        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
79        // Safety: CreepClaimReactorErrorCode discriminants are always error code
80        // values, and thus the Result returned here will always be an `Err` variant, so
81        // we can always extract the error without panicking
82        Self::result_from_i8(value as i8).unwrap_err()
83    }
84}
85
86/// Error codes used by [Creep::attack](crate::Creep::attack).
87///
88/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.attack).
89///
90/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L593)
91#[derive(
92    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
93)]
94#[repr(i8)]
95pub enum CreepAttackErrorCode {
96    NotOwner = -1,
97    Busy = -4,
98    InvalidTarget = -7,
99    NotInRange = -9,
100    NoBodypart = -12,
101}
102
103impl FromReturnCode for CreepAttackErrorCode {
104    type Error = Self;
105
106    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
107        let maybe_result = Self::try_result_from_i8(val);
108        #[cfg(feature = "unsafe-return-conversion")]
109        unsafe {
110            maybe_result.unwrap_unchecked()
111        }
112        #[cfg(not(feature = "unsafe-return-conversion"))]
113        maybe_result.unwrap()
114    }
115
116    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
117        match val {
118            0 => Some(Ok(())),
119            -1 => Some(Err(CreepAttackErrorCode::NotOwner)),
120            -4 => Some(Err(CreepAttackErrorCode::Busy)),
121            -7 => Some(Err(CreepAttackErrorCode::InvalidTarget)),
122            -9 => Some(Err(CreepAttackErrorCode::NotInRange)),
123            -12 => Some(Err(CreepAttackErrorCode::NoBodypart)),
124            _ => None,
125        }
126    }
127}
128
129impl fmt::Display for CreepAttackErrorCode {
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        let msg: &'static str = match self {
132            CreepAttackErrorCode::NotOwner => "you are not the owner of this creep",
133            CreepAttackErrorCode::Busy => "the creep is still being spawned",
134            CreepAttackErrorCode::InvalidTarget => "the target is not a valid attackable object",
135            CreepAttackErrorCode::NotInRange => "the target is too far away",
136            CreepAttackErrorCode::NoBodypart => {
137                "there are no attack body parts in this creep’s body"
138            }
139        };
140
141        write!(f, "{}", msg)
142    }
143}
144
145impl Error for CreepAttackErrorCode {}
146
147impl From<CreepAttackErrorCode> for ErrorCode {
148    fn from(value: CreepAttackErrorCode) -> Self {
149        // Safety: CreepAttackErrorCode is repr(i8), so we can cast it to get the
150        // discriminant value, which will match the raw return code value that ErrorCode
151        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
152        // Safety: CreepAttackErrorCode discriminants are always error code values, and
153        // thus the Result returned here will always be an `Err` variant, so we can
154        // always extract the error without panicking
155        Self::result_from_i8(value as i8).unwrap_err()
156    }
157}
158
159/// Error codes used by
160/// [Creep::attack_controller](crate::Creep::attack_controller).
161///
162/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.attackController).
163///
164/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L885)
165#[derive(
166    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
167)]
168#[repr(i8)]
169pub enum AttackControllerErrorCode {
170    NotOwner = -1,
171    Busy = -4,
172    InvalidTarget = -7,
173    NotInRange = -9,
174    Tired = -11,
175    NoBodypart = -12,
176}
177
178impl FromReturnCode for AttackControllerErrorCode {
179    type Error = Self;
180
181    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
182        let maybe_result = Self::try_result_from_i8(val);
183        #[cfg(feature = "unsafe-return-conversion")]
184        unsafe {
185            maybe_result.unwrap_unchecked()
186        }
187        #[cfg(not(feature = "unsafe-return-conversion"))]
188        maybe_result.unwrap()
189    }
190
191    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
192        match val {
193            0 => Some(Ok(())),
194            -1 => Some(Err(AttackControllerErrorCode::NotOwner)),
195            -4 => Some(Err(AttackControllerErrorCode::Busy)),
196            -7 => Some(Err(AttackControllerErrorCode::InvalidTarget)),
197            -9 => Some(Err(AttackControllerErrorCode::NotInRange)),
198            -11 => Some(Err(AttackControllerErrorCode::Tired)),
199            -12 => Some(Err(AttackControllerErrorCode::NoBodypart)),
200            _ => None,
201        }
202    }
203}
204
205impl fmt::Display for AttackControllerErrorCode {
206    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207        let msg: &'static str = match self {
208            AttackControllerErrorCode::NotOwner => "you are not the owner of this creep",
209            AttackControllerErrorCode::Busy => "the creep is still being spawned",
210            AttackControllerErrorCode::InvalidTarget => {
211                "the target is not a valid owned or reserved controller object"
212            }
213            AttackControllerErrorCode::NotInRange => "the target is too far away",
214            AttackControllerErrorCode::Tired => {
215                "you have to wait until the next attack is possible"
216            }
217            AttackControllerErrorCode::NoBodypart => {
218                "there are not enough claim body parts in this creep’s body"
219            }
220        };
221
222        write!(f, "{}", msg)
223    }
224}
225
226impl Error for AttackControllerErrorCode {}
227
228impl From<AttackControllerErrorCode> for ErrorCode {
229    fn from(value: AttackControllerErrorCode) -> Self {
230        // Safety: AttackControllerErrorCode is repr(i8), so we can cast it to get the
231        // discriminant value, which will match the raw return code value that ErrorCode
232        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
233        // Safety: AttackControllerErrorCode discriminants are always error code values,
234        // and thus the Result returned here will always be an `Err` variant, so we can
235        // always extract the error without panicking
236        Self::result_from_i8(value as i8).unwrap_err()
237    }
238}
239
240/// Error codes used by [Creep::build](crate::Creep::build).
241///
242/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.build).
243///
244/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L762)
245#[derive(
246    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
247)]
248#[repr(i8)]
249pub enum BuildErrorCode {
250    NotOwner = -1,
251    Busy = -4,
252    NotEnoughResources = -6,
253    InvalidTarget = -7,
254    NotInRange = -9,
255    NoBodypart = -12,
256}
257
258impl FromReturnCode for BuildErrorCode {
259    type Error = Self;
260
261    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
262        let maybe_result = Self::try_result_from_i8(val);
263        #[cfg(feature = "unsafe-return-conversion")]
264        unsafe {
265            maybe_result.unwrap_unchecked()
266        }
267        #[cfg(not(feature = "unsafe-return-conversion"))]
268        maybe_result.unwrap()
269    }
270
271    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
272        match val {
273            0 => Some(Ok(())),
274            -1 => Some(Err(BuildErrorCode::NotOwner)),
275            -4 => Some(Err(BuildErrorCode::Busy)),
276            -6 => Some(Err(BuildErrorCode::NotEnoughResources)),
277            -7 => Some(Err(BuildErrorCode::InvalidTarget)),
278            -9 => Some(Err(BuildErrorCode::NotInRange)),
279            -12 => Some(Err(BuildErrorCode::NoBodypart)),
280            _ => None,
281        }
282    }
283}
284
285impl fmt::Display for BuildErrorCode {
286    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287        let msg: &'static str = match self {
288            BuildErrorCode::NotOwner => "you are not the owner of this creep",
289            BuildErrorCode::Busy => "the creep is still being spawned",
290            BuildErrorCode::NotEnoughResources => "the creep does not have any carried energy",
291            BuildErrorCode::InvalidTarget => "the target is not a valid construction site object or the structure cannot be built here (probably because of a creep at the same square)",
292            BuildErrorCode::NotInRange => "the target is too far away",
293            BuildErrorCode::NoBodypart => "there are no work body parts in this creep’s body",
294        };
295
296        write!(f, "{}", msg)
297    }
298}
299
300impl Error for BuildErrorCode {}
301
302impl From<BuildErrorCode> for ErrorCode {
303    fn from(value: BuildErrorCode) -> Self {
304        // Safety: BuildErrorCode is repr(i8), so we can cast it to get the discriminant
305        // value, which will match the raw return code value that ErrorCode expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
306        // Safety: BuildErrorCode discriminants are always error code values, and thus
307        // the Result returned here will always be an `Err` variant, so we can always
308        // extract the error without panicking
309        Self::result_from_i8(value as i8).unwrap_err()
310    }
311}
312
313/// Error codes used by [Creep::cancel_order](crate::Creep::cancel_order).
314///
315/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.cancelOrder).
316///
317/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L1008)
318#[derive(
319    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
320)]
321#[repr(i8)]
322pub enum CreepCancelOrderErrorCode {
323    NotFound = -5,
324}
325
326impl FromReturnCode for CreepCancelOrderErrorCode {
327    type Error = Self;
328
329    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
330        let maybe_result = Self::try_result_from_i8(val);
331        #[cfg(feature = "unsafe-return-conversion")]
332        unsafe {
333            maybe_result.unwrap_unchecked()
334        }
335        #[cfg(not(feature = "unsafe-return-conversion"))]
336        maybe_result.unwrap()
337    }
338
339    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
340        match val {
341            0 => Some(Ok(())),
342            -5 => Some(Err(CreepCancelOrderErrorCode::NotFound)),
343            _ => None,
344        }
345    }
346}
347
348impl fmt::Display for CreepCancelOrderErrorCode {
349    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350        let msg: &'static str = match self {
351            CreepCancelOrderErrorCode::NotFound => "the order with the specified name is not found",
352        };
353
354        write!(f, "{}", msg)
355    }
356}
357
358impl Error for CreepCancelOrderErrorCode {}
359
360impl From<CreepCancelOrderErrorCode> for ErrorCode {
361    fn from(value: CreepCancelOrderErrorCode) -> Self {
362        // Safety: CreepCancelOrderErrorCode is repr(i8), so we can cast it to get the
363        // discriminant value, which will match the raw return code value that ErrorCode
364        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
365        // Safety: CreepCancelOrderErrorCode discriminants are always error code values,
366        // and thus the Result returned here will always be an `Err` variant, so we can
367        // always extract the error without panicking
368        Self::result_from_i8(value as i8).unwrap_err()
369    }
370}
371
372/// Error codes used by
373/// [Creep::claim_controller](crate::Creep::claim_controller).
374///
375/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.claimController).
376///
377/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L839)
378#[derive(
379    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
380)]
381#[repr(i8)]
382pub enum ClaimControllerErrorCode {
383    NotOwner = -1,
384    Busy = -4,
385    InvalidTarget = -7,
386    Full = -8,
387    NotInRange = -9,
388    NoBodypart = -12,
389    GclNotEnough = -15,
390    AccessDenied = -16,
391}
392
393impl FromReturnCode for ClaimControllerErrorCode {
394    type Error = Self;
395
396    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
397        let maybe_result = Self::try_result_from_i8(val);
398        #[cfg(feature = "unsafe-return-conversion")]
399        unsafe {
400            maybe_result.unwrap_unchecked()
401        }
402        #[cfg(not(feature = "unsafe-return-conversion"))]
403        maybe_result.unwrap()
404    }
405
406    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
407        match val {
408            0 => Some(Ok(())),
409            -1 => Some(Err(ClaimControllerErrorCode::NotOwner)),
410            -4 => Some(Err(ClaimControllerErrorCode::Busy)),
411            -7 => Some(Err(ClaimControllerErrorCode::InvalidTarget)),
412            -8 => Some(Err(ClaimControllerErrorCode::Full)),
413            -9 => Some(Err(ClaimControllerErrorCode::NotInRange)),
414            -12 => Some(Err(ClaimControllerErrorCode::NoBodypart)),
415            -15 => Some(Err(ClaimControllerErrorCode::GclNotEnough)),
416            -16 => Some(Err(ClaimControllerErrorCode::AccessDenied)),
417            _ => None,
418        }
419    }
420}
421
422impl fmt::Display for ClaimControllerErrorCode {
423    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424        let msg: &'static str = match self {
425            ClaimControllerErrorCode::NotOwner => "you are not the owner of this creep",
426            ClaimControllerErrorCode::Busy => "the creep is still being spawned",
427            ClaimControllerErrorCode::InvalidTarget => {
428                "the target is not a valid neutral controller object"
429            }
430            ClaimControllerErrorCode::Full => {
431                "you cannot claim more than 3 rooms in the novice area"
432            }
433            ClaimControllerErrorCode::NotInRange => "the target is too far away",
434            ClaimControllerErrorCode::NoBodypart => {
435                "there are no claim body parts in this creep’s body"
436            }
437            ClaimControllerErrorCode::GclNotEnough => "your global control level is not enough",
438            ClaimControllerErrorCode::AccessDenied => {
439                "you do not have access to this restricted shard"
440            }
441        };
442
443        write!(f, "{}", msg)
444    }
445}
446
447impl Error for ClaimControllerErrorCode {}
448
449impl From<ClaimControllerErrorCode> for ErrorCode {
450    fn from(value: ClaimControllerErrorCode) -> Self {
451        // Safety: ClaimControllerErrorCode is repr(i8), so we can cast it to get the
452        // discriminant value, which will match the raw return code value that ErrorCode
453        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
454        // Safety: ClaimControllerErrorCode discriminants are always error code values,
455        // and thus the Result returned here will always be an `Err` variant, so we can
456        // always extract the error without panicking
457        Self::result_from_i8(value as i8).unwrap_err()
458    }
459}
460
461/// Error codes used by [Creep::dismantle](crate::Creep::dismantle).
462///
463/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.dismantle).
464///
465/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L1016)
466#[derive(
467    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
468)]
469#[repr(i8)]
470pub enum DismantleErrorCode {
471    NotOwner = -1,
472    Busy = -4,
473    InvalidTarget = -7,
474    NotInRange = -9,
475    NoBodypart = -12,
476}
477
478impl FromReturnCode for DismantleErrorCode {
479    type Error = Self;
480
481    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
482        let maybe_result = Self::try_result_from_i8(val);
483        #[cfg(feature = "unsafe-return-conversion")]
484        unsafe {
485            maybe_result.unwrap_unchecked()
486        }
487        #[cfg(not(feature = "unsafe-return-conversion"))]
488        maybe_result.unwrap()
489    }
490
491    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
492        match val {
493            0 => Some(Ok(())),
494            -1 => Some(Err(DismantleErrorCode::NotOwner)),
495            -4 => Some(Err(DismantleErrorCode::Busy)),
496            -7 => Some(Err(DismantleErrorCode::InvalidTarget)),
497            -9 => Some(Err(DismantleErrorCode::NotInRange)),
498            -12 => Some(Err(DismantleErrorCode::NoBodypart)),
499            _ => None,
500        }
501    }
502}
503
504impl fmt::Display for DismantleErrorCode {
505    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
506        let msg: &'static str = match self {
507            DismantleErrorCode::NotOwner => "you are not the owner of this creep",
508            DismantleErrorCode::Busy => "the creep is still being spawned",
509            DismantleErrorCode::InvalidTarget => "the target is not a valid structure object",
510            DismantleErrorCode::NotInRange => "the target is too far away",
511            DismantleErrorCode::NoBodypart => "there are no work body parts in this creep’s body",
512        };
513
514        write!(f, "{}", msg)
515    }
516}
517
518impl Error for DismantleErrorCode {}
519
520impl From<DismantleErrorCode> for ErrorCode {
521    fn from(value: DismantleErrorCode) -> Self {
522        // Safety: DismantleErrorCode is repr(i8), so we can cast it to get the
523        // discriminant value, which will match the raw return code value that ErrorCode
524        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
525        // Safety: DismantleErrorCode discriminants are always error code values, and
526        // thus the Result returned here will always be an `Err` variant, so we can
527        // always extract the error without panicking
528        Self::result_from_i8(value as i8).unwrap_err()
529    }
530}
531
532/// Error codes used by
533/// [Creep::generate_safe_mode](crate::Creep::generate_safe_mode).
534///
535/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.generateSafeMode).
536///
537/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L1049)
538#[derive(
539    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
540)]
541#[repr(i8)]
542pub enum GenerateSafeModeErrorCode {
543    NotOwner = -1,
544    Busy = -4,
545    NotEnoughResources = -6,
546    InvalidTarget = -7,
547    NotInRange = -9,
548}
549
550impl FromReturnCode for GenerateSafeModeErrorCode {
551    type Error = Self;
552
553    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
554        let maybe_result = Self::try_result_from_i8(val);
555        #[cfg(feature = "unsafe-return-conversion")]
556        unsafe {
557            maybe_result.unwrap_unchecked()
558        }
559        #[cfg(not(feature = "unsafe-return-conversion"))]
560        maybe_result.unwrap()
561    }
562
563    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
564        match val {
565            0 => Some(Ok(())),
566            -1 => Some(Err(GenerateSafeModeErrorCode::NotOwner)),
567            -4 => Some(Err(GenerateSafeModeErrorCode::Busy)),
568            -6 => Some(Err(GenerateSafeModeErrorCode::NotEnoughResources)),
569            -7 => Some(Err(GenerateSafeModeErrorCode::InvalidTarget)),
570            -9 => Some(Err(GenerateSafeModeErrorCode::NotInRange)),
571            _ => None,
572        }
573    }
574}
575
576impl fmt::Display for GenerateSafeModeErrorCode {
577    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
578        let msg: &'static str = match self {
579            GenerateSafeModeErrorCode::NotOwner => "you are not the owner of this creep",
580            GenerateSafeModeErrorCode::Busy => "the creep is still being spawned",
581            GenerateSafeModeErrorCode::NotEnoughResources => {
582                "the creep does not have enough ghodium"
583            }
584            GenerateSafeModeErrorCode::InvalidTarget => {
585                "the target is not a valid controller object"
586            }
587            GenerateSafeModeErrorCode::NotInRange => "the target is too far away",
588        };
589
590        write!(f, "{}", msg)
591    }
592}
593
594impl Error for GenerateSafeModeErrorCode {}
595
596impl From<GenerateSafeModeErrorCode> for ErrorCode {
597    fn from(value: GenerateSafeModeErrorCode) -> Self {
598        // Safety: GenerateSafeModeErrorCode is repr(i8), so we can cast it to get the
599        // discriminant value, which will match the raw return code value that ErrorCode
600        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
601        // Safety: GenerateSafeModeErrorCode discriminants are always error code values,
602        // and thus the Result returned here will always be an `Err` variant, so we can
603        // always extract the error without panicking
604        Self::result_from_i8(value as i8).unwrap_err()
605    }
606}
607
608/// Error codes used by [Creep::harvest](crate::Creep::harvest).
609///
610/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.harvest).
611///
612/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L335)
613#[derive(
614    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
615)]
616#[repr(i8)]
617pub enum HarvestErrorCode {
618    NotOwner = -1,
619    Busy = -4,
620    NotFound = -5,
621    NotEnoughResources = -6,
622    InvalidTarget = -7,
623    NotInRange = -9,
624    Tired = -11,
625    NoBodypart = -12,
626    RclNotEnough = -14,
627}
628
629impl FromReturnCode for HarvestErrorCode {
630    type Error = Self;
631
632    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
633        let maybe_result = Self::try_result_from_i8(val);
634        #[cfg(feature = "unsafe-return-conversion")]
635        unsafe {
636            maybe_result.unwrap_unchecked()
637        }
638        #[cfg(not(feature = "unsafe-return-conversion"))]
639        maybe_result.unwrap()
640    }
641
642    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
643        match val {
644            0 => Some(Ok(())),
645            -1 => Some(Err(HarvestErrorCode::NotOwner)),
646            -4 => Some(Err(HarvestErrorCode::Busy)),
647            -5 => Some(Err(HarvestErrorCode::NotFound)),
648            -6 => Some(Err(HarvestErrorCode::NotEnoughResources)),
649            -7 => Some(Err(HarvestErrorCode::InvalidTarget)),
650            -9 => Some(Err(HarvestErrorCode::NotInRange)),
651            -11 => Some(Err(HarvestErrorCode::Tired)),
652            -12 => Some(Err(HarvestErrorCode::NoBodypart)),
653            -14 => Some(Err(HarvestErrorCode::RclNotEnough)),
654            _ => None,
655        }
656    }
657}
658
659impl fmt::Display for HarvestErrorCode {
660    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
661        let msg: &'static str = match self {
662            HarvestErrorCode::NotOwner => "you are not the owner of this creep, or the room controller is owned or reserved by another player",
663            HarvestErrorCode::Busy => "the creep is still being spawned",
664            HarvestErrorCode::NotFound => "extractor not found. you must build an extractor structure to harvest minerals. learn more",
665            HarvestErrorCode::NotEnoughResources => "the target does not contain any harvestable energy or mineral",
666            HarvestErrorCode::InvalidTarget => "the target is not a valid source or mineral object",
667            HarvestErrorCode::NotInRange => "the target is too far away",
668            HarvestErrorCode::Tired => "the extractor or the deposit is still cooling down",
669            HarvestErrorCode::NoBodypart => "there are no work body parts in this creep’s body",
670            HarvestErrorCode::RclNotEnough => "room controller level insufficient to use the extractor",
671        };
672
673        write!(f, "{}", msg)
674    }
675}
676
677impl Error for HarvestErrorCode {}
678
679impl From<HarvestErrorCode> for ErrorCode {
680    fn from(value: HarvestErrorCode) -> Self {
681        // Safety: HarvestErrorCode is repr(i8), so we can cast it to get the
682        // discriminant value, which will match the raw return code value that ErrorCode
683        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
684        // Safety: HarvestErrorCode discriminants are always error code values, and thus
685        // the Result returned here will always be an `Err` variant, so we can always
686        // extract the error without panicking
687        Self::result_from_i8(value as i8).unwrap_err()
688    }
689}
690
691/// Error codes used by [Creep::heal](crate::Creep::heal).
692///
693/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.heal).
694///
695/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L678)
696#[derive(
697    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
698)]
699#[repr(i8)]
700pub enum CreepHealErrorCode {
701    NotOwner = -1,
702    Busy = -4,
703    InvalidTarget = -7,
704    NotInRange = -9,
705    NoBodypart = -12,
706}
707
708impl FromReturnCode for CreepHealErrorCode {
709    type Error = Self;
710
711    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
712        let maybe_result = Self::try_result_from_i8(val);
713        #[cfg(feature = "unsafe-return-conversion")]
714        unsafe {
715            maybe_result.unwrap_unchecked()
716        }
717        #[cfg(not(feature = "unsafe-return-conversion"))]
718        maybe_result.unwrap()
719    }
720
721    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
722        match val {
723            0 => Some(Ok(())),
724            -1 => Some(Err(CreepHealErrorCode::NotOwner)),
725            -4 => Some(Err(CreepHealErrorCode::Busy)),
726            -7 => Some(Err(CreepHealErrorCode::InvalidTarget)),
727            -9 => Some(Err(CreepHealErrorCode::NotInRange)),
728            -12 => Some(Err(CreepHealErrorCode::NoBodypart)),
729            _ => None,
730        }
731    }
732}
733
734impl fmt::Display for CreepHealErrorCode {
735    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
736        let msg: &'static str = match self {
737            CreepHealErrorCode::NotOwner => "you are not the owner of this creep",
738            CreepHealErrorCode::Busy => "the creep is still being spawned",
739            CreepHealErrorCode::InvalidTarget => "the target is not a valid creep object",
740            CreepHealErrorCode::NotInRange => "the target is too far away",
741            CreepHealErrorCode::NoBodypart => "there are no heal body parts in this creep’s body",
742        };
743
744        write!(f, "{}", msg)
745    }
746}
747
748impl Error for CreepHealErrorCode {}
749
750impl From<CreepHealErrorCode> for ErrorCode {
751    fn from(value: CreepHealErrorCode) -> Self {
752        // Safety: CreepHealErrorCode is repr(i8), so we can cast it to get the
753        // discriminant value, which will match the raw return code value that ErrorCode
754        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
755        // Safety: CreepHealErrorCode discriminants are always error code values, and
756        // thus the Result returned here will always be an `Err` variant, so we can
757        // always extract the error without panicking
758        Self::result_from_i8(value as i8).unwrap_err()
759    }
760}
761
762/// Error codes used by [Creep::move_direction](crate::Creep::move_direction).
763///
764/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.move).
765///
766/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L126)
767#[derive(
768    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
769)]
770#[repr(i8)]
771pub enum CreepMoveDirectionErrorCode {
772    NotOwner = -1,
773    Busy = -4,
774    InvalidArgs = -10,
775    Tired = -11,
776    NoBodypart = -12,
777}
778
779impl FromReturnCode for CreepMoveDirectionErrorCode {
780    type Error = Self;
781
782    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
783        let maybe_result = Self::try_result_from_i8(val);
784        #[cfg(feature = "unsafe-return-conversion")]
785        unsafe {
786            maybe_result.unwrap_unchecked()
787        }
788        #[cfg(not(feature = "unsafe-return-conversion"))]
789        maybe_result.unwrap()
790    }
791
792    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
793        match val {
794            0 => Some(Ok(())),
795            -1 => Some(Err(CreepMoveDirectionErrorCode::NotOwner)),
796            -4 => Some(Err(CreepMoveDirectionErrorCode::Busy)),
797            -10 => Some(Err(CreepMoveDirectionErrorCode::InvalidArgs)),
798            -11 => Some(Err(CreepMoveDirectionErrorCode::Tired)),
799            -12 => Some(Err(CreepMoveDirectionErrorCode::NoBodypart)),
800            _ => None,
801        }
802    }
803}
804
805impl fmt::Display for CreepMoveDirectionErrorCode {
806    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
807        let msg: &'static str = match self {
808            CreepMoveDirectionErrorCode::NotOwner => "you are not the owner of this creep",
809            CreepMoveDirectionErrorCode::Busy => "the creep is still being spawned",
810            CreepMoveDirectionErrorCode::InvalidArgs => "the provided direction is incorrect",
811            CreepMoveDirectionErrorCode::Tired => "the fatigue indicator of the creep is non-zero",
812            CreepMoveDirectionErrorCode::NoBodypart => {
813                "there are no move body parts in this creep’s body"
814            }
815        };
816
817        write!(f, "{}", msg)
818    }
819}
820
821impl Error for CreepMoveDirectionErrorCode {}
822
823impl From<CreepMoveDirectionErrorCode> for ErrorCode {
824    fn from(value: CreepMoveDirectionErrorCode) -> Self {
825        // Safety: CreepMoveDirectionErrorCode is repr(i8), so we can cast it to get the
826        // discriminant value, which will match the raw return code value that ErrorCode
827        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
828        // Safety: CreepMoveDirectionErrorCode discriminants are always error code
829        // values, and thus the Result returned here will always be an `Err` variant, so
830        // we can always extract the error without panicking
831        Self::result_from_i8(value as i8).unwrap_err()
832    }
833}
834
835/// Error codes used by [Creep::move_pulled_by](crate::Creep::move_pulled_by).
836///
837/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.move).
838///
839/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L126)
840#[derive(
841    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
842)]
843#[repr(i8)]
844pub enum CreepMovePulledByErrorCode {
845    NotOwner = -1,
846    Busy = -4,
847    NotInRange = -9,
848    InvalidArgs = -10,
849}
850
851impl FromReturnCode for CreepMovePulledByErrorCode {
852    type Error = Self;
853
854    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
855        let maybe_result = Self::try_result_from_i8(val);
856        #[cfg(feature = "unsafe-return-conversion")]
857        unsafe {
858            maybe_result.unwrap_unchecked()
859        }
860        #[cfg(not(feature = "unsafe-return-conversion"))]
861        maybe_result.unwrap()
862    }
863
864    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
865        match val {
866            0 => Some(Ok(())),
867            -1 => Some(Err(CreepMovePulledByErrorCode::NotOwner)),
868            -4 => Some(Err(CreepMovePulledByErrorCode::Busy)),
869            -9 => Some(Err(CreepMovePulledByErrorCode::NotInRange)),
870            -10 => Some(Err(CreepMovePulledByErrorCode::InvalidArgs)),
871            _ => None,
872        }
873    }
874}
875
876impl fmt::Display for CreepMovePulledByErrorCode {
877    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
878        let msg: &'static str = match self {
879            CreepMovePulledByErrorCode::NotOwner => "you are not the owner of this creep",
880            CreepMovePulledByErrorCode::Busy => "the creep is still being spawned",
881            CreepMovePulledByErrorCode::NotInRange => "the target creep is too far away",
882            CreepMovePulledByErrorCode::InvalidArgs => "the provided direction is incorrect",
883        };
884
885        write!(f, "{}", msg)
886    }
887}
888
889impl Error for CreepMovePulledByErrorCode {}
890
891impl From<CreepMovePulledByErrorCode> for ErrorCode {
892    fn from(value: CreepMovePulledByErrorCode) -> Self {
893        // Safety: CreepMovePulledByErrorCode is repr(i8), so we can cast it to get the
894        // discriminant value, which will match the raw return code value that ErrorCode
895        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
896        // Safety: CreepMovePulledByErrorCode discriminants are always error code
897        // values, and thus the Result returned here will always be an `Err` variant, so
898        // we can always extract the error without panicking
899        Self::result_from_i8(value as i8).unwrap_err()
900    }
901}
902
903/// Error codes used by [Creep::move_by_path](crate::Creep::move_by_path).
904///
905/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.moveByPath).
906///
907/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L305)
908#[derive(
909    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
910)]
911#[repr(i8)]
912pub enum CreepMoveByPathErrorCode {
913    NotOwner = -1,
914    Busy = -4,
915    NotFound = -5,
916    InvalidArgs = -10,
917    Tired = -11,
918    NoBodypart = -12,
919}
920
921impl FromReturnCode for CreepMoveByPathErrorCode {
922    type Error = Self;
923
924    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
925        let maybe_result = Self::try_result_from_i8(val);
926        #[cfg(feature = "unsafe-return-conversion")]
927        unsafe {
928            maybe_result.unwrap_unchecked()
929        }
930        #[cfg(not(feature = "unsafe-return-conversion"))]
931        maybe_result.unwrap()
932    }
933
934    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
935        match val {
936            0 => Some(Ok(())),
937            -1 => Some(Err(CreepMoveByPathErrorCode::NotOwner)),
938            -4 => Some(Err(CreepMoveByPathErrorCode::Busy)),
939            -5 => Some(Err(CreepMoveByPathErrorCode::NotFound)),
940            -10 => Some(Err(CreepMoveByPathErrorCode::InvalidArgs)),
941            -11 => Some(Err(CreepMoveByPathErrorCode::Tired)),
942            -12 => Some(Err(CreepMoveByPathErrorCode::NoBodypart)),
943            _ => None,
944        }
945    }
946}
947
948impl fmt::Display for CreepMoveByPathErrorCode {
949    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
950        let msg: &'static str = match self {
951            CreepMoveByPathErrorCode::NotOwner => "you are not the owner of this creep",
952            CreepMoveByPathErrorCode::Busy => "the creep is still being spawned",
953            CreepMoveByPathErrorCode::NotFound => {
954                "the specified path doesn't match the creep's location"
955            }
956            CreepMoveByPathErrorCode::InvalidArgs => "path is not a valid path array",
957            CreepMoveByPathErrorCode::Tired => "the fatigue indicator of the creep is non-zero",
958            CreepMoveByPathErrorCode::NoBodypart => {
959                "there are no move body parts in this creep’s body"
960            }
961        };
962
963        write!(f, "{}", msg)
964    }
965}
966
967impl Error for CreepMoveByPathErrorCode {}
968
969impl From<CreepMoveByPathErrorCode> for ErrorCode {
970    fn from(value: CreepMoveByPathErrorCode) -> Self {
971        // Safety: CreepMoveByPathErrorCode is repr(i8), so we can cast it to get the
972        // discriminant value, which will match the raw return code value that ErrorCode
973        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
974        // Safety: CreepMoveByPathErrorCode discriminants are always error code values,
975        // and thus the Result returned here will always be an `Err` variant, so we can
976        // always extract the error without panicking
977        Self::result_from_i8(value as i8).unwrap_err()
978    }
979}
980
981/// Error codes used by [Creep::move_to](crate::Creep#method.move_to).
982///
983/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.moveTo).
984///
985/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L158)
986#[derive(
987    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
988)]
989#[repr(i8)]
990pub enum CreepMoveToErrorCode {
991    NotOwner = -1,
992    NoPath = -2,
993    Busy = -4,
994    NotFound = -5,
995    InvalidTarget = -7,
996    Tired = -11,
997    NoBodypart = -12,
998}
999
1000impl FromReturnCode for CreepMoveToErrorCode {
1001    type Error = Self;
1002
1003    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1004        let maybe_result = Self::try_result_from_i8(val);
1005        #[cfg(feature = "unsafe-return-conversion")]
1006        unsafe {
1007            maybe_result.unwrap_unchecked()
1008        }
1009        #[cfg(not(feature = "unsafe-return-conversion"))]
1010        maybe_result.unwrap()
1011    }
1012
1013    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1014        match val {
1015            0 => Some(Ok(())),
1016            -1 => Some(Err(CreepMoveToErrorCode::NotOwner)),
1017            -2 => Some(Err(CreepMoveToErrorCode::NoPath)),
1018            -4 => Some(Err(CreepMoveToErrorCode::Busy)),
1019            -5 => Some(Err(CreepMoveToErrorCode::NotFound)),
1020            -7 => Some(Err(CreepMoveToErrorCode::InvalidTarget)),
1021            -11 => Some(Err(CreepMoveToErrorCode::Tired)),
1022            -12 => Some(Err(CreepMoveToErrorCode::NoBodypart)),
1023            _ => None,
1024        }
1025    }
1026}
1027
1028impl fmt::Display for CreepMoveToErrorCode {
1029    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1030        let msg: &'static str = match self {
1031            CreepMoveToErrorCode::NotOwner => "you are not the owner of this creep",
1032            CreepMoveToErrorCode::NoPath => "no path to the target could be found",
1033            CreepMoveToErrorCode::Busy => "the creep is still being spawned",
1034            CreepMoveToErrorCode::NotFound => "the creep has no memorized path to reuse",
1035            CreepMoveToErrorCode::InvalidTarget => "the target provided is invalid",
1036            CreepMoveToErrorCode::Tired => "the fatigue indicator of the creep is non-zero",
1037            CreepMoveToErrorCode::NoBodypart => "there are no move body parts in this creep’s body",
1038        };
1039
1040        write!(f, "{}", msg)
1041    }
1042}
1043
1044impl Error for CreepMoveToErrorCode {}
1045
1046impl From<CreepMoveToErrorCode> for ErrorCode {
1047    fn from(value: CreepMoveToErrorCode) -> Self {
1048        // Safety: CreepMoveToErrorCode is repr(i8), so we can cast it to get the
1049        // discriminant value, which will match the raw return code value that ErrorCode
1050        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1051        // Safety: CreepMoveToErrorCode discriminants are always error code values, and
1052        // thus the Result returned here will always be an `Err` variant, so we can
1053        // always extract the error without panicking
1054        Self::result_from_i8(value as i8).unwrap_err()
1055    }
1056}
1057
1058/// Error codes used by [Creep::pull](crate::Creep::pull).
1059///
1060/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.pull).
1061///
1062/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L1093)
1063#[derive(
1064    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1065)]
1066#[repr(i8)]
1067pub enum PullErrorCode {
1068    NotOwner = -1,
1069    Busy = -4,
1070    InvalidTarget = -7,
1071    NotInRange = -9,
1072}
1073
1074impl FromReturnCode for PullErrorCode {
1075    type Error = Self;
1076
1077    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1078        let maybe_result = Self::try_result_from_i8(val);
1079        #[cfg(feature = "unsafe-return-conversion")]
1080        unsafe {
1081            maybe_result.unwrap_unchecked()
1082        }
1083        #[cfg(not(feature = "unsafe-return-conversion"))]
1084        maybe_result.unwrap()
1085    }
1086
1087    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1088        match val {
1089            0 => Some(Ok(())),
1090            -1 => Some(Err(PullErrorCode::NotOwner)),
1091            -4 => Some(Err(PullErrorCode::Busy)),
1092            -7 => Some(Err(PullErrorCode::InvalidTarget)),
1093            -9 => Some(Err(PullErrorCode::NotInRange)),
1094            _ => None,
1095        }
1096    }
1097}
1098
1099impl fmt::Display for PullErrorCode {
1100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1101        let msg: &'static str = match self {
1102            PullErrorCode::NotOwner => "you are not the owner of this creep",
1103            PullErrorCode::Busy => "the creep is still being spawned",
1104            PullErrorCode::InvalidTarget => "the target provided is invalid",
1105            PullErrorCode::NotInRange => "the target is too far away",
1106        };
1107
1108        write!(f, "{}", msg)
1109    }
1110}
1111
1112impl Error for PullErrorCode {}
1113
1114impl From<PullErrorCode> for ErrorCode {
1115    fn from(value: PullErrorCode) -> Self {
1116        // Safety: PullErrorCode is repr(i8), so we can cast it to get the discriminant
1117        // value, which will match the raw return code value that ErrorCode expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1118        // Safety: PullErrorCode discriminants are always error code values, and thus
1119        // the Result returned here will always be an `Err` variant, so we can always
1120        // extract the error without panicking
1121        Self::result_from_i8(value as i8).unwrap_err()
1122    }
1123}
1124
1125/// Error codes used by [Creep::ranged_attack](crate::Creep::ranged_attack).
1126///
1127/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.rangedAttack).
1128///
1129/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L626)
1130#[derive(
1131    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1132)]
1133#[repr(i8)]
1134pub enum RangedAttackErrorCode {
1135    NotOwner = -1,
1136    Busy = -4,
1137    InvalidTarget = -7,
1138    NotInRange = -9,
1139    NoBodypart = -12,
1140}
1141
1142impl FromReturnCode for RangedAttackErrorCode {
1143    type Error = Self;
1144
1145    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1146        let maybe_result = Self::try_result_from_i8(val);
1147        #[cfg(feature = "unsafe-return-conversion")]
1148        unsafe {
1149            maybe_result.unwrap_unchecked()
1150        }
1151        #[cfg(not(feature = "unsafe-return-conversion"))]
1152        maybe_result.unwrap()
1153    }
1154
1155    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1156        match val {
1157            0 => Some(Ok(())),
1158            -1 => Some(Err(RangedAttackErrorCode::NotOwner)),
1159            -4 => Some(Err(RangedAttackErrorCode::Busy)),
1160            -7 => Some(Err(RangedAttackErrorCode::InvalidTarget)),
1161            -9 => Some(Err(RangedAttackErrorCode::NotInRange)),
1162            -12 => Some(Err(RangedAttackErrorCode::NoBodypart)),
1163            _ => None,
1164        }
1165    }
1166}
1167
1168impl fmt::Display for RangedAttackErrorCode {
1169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1170        let msg: &'static str = match self {
1171            RangedAttackErrorCode::NotOwner => "you are not the owner of this creep",
1172            RangedAttackErrorCode::Busy => "the creep is still being spawned",
1173            RangedAttackErrorCode::InvalidTarget => "the target is not a valid attackable object",
1174            RangedAttackErrorCode::NotInRange => "the target is too far away",
1175            RangedAttackErrorCode::NoBodypart => {
1176                "there are no ranged_attack body parts in this creep’s body"
1177            }
1178        };
1179
1180        write!(f, "{}", msg)
1181    }
1182}
1183
1184impl Error for RangedAttackErrorCode {}
1185
1186impl From<RangedAttackErrorCode> for ErrorCode {
1187    fn from(value: RangedAttackErrorCode) -> Self {
1188        // Safety: RangedAttackErrorCode is repr(i8), so we can cast it to get the
1189        // discriminant value, which will match the raw return code value that ErrorCode
1190        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1191        // Safety: RangedAttackErrorCode discriminants are always error code values, and
1192        // thus the Result returned here will always be an `Err` variant, so we can
1193        // always extract the error without panicking
1194        Self::result_from_i8(value as i8).unwrap_err()
1195    }
1196}
1197
1198/// Error codes used by [Creep::ranged_heal](crate::Creep::ranged_heal).
1199///
1200/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.rangedHeal).
1201///
1202/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L706)
1203#[derive(
1204    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1205)]
1206#[repr(i8)]
1207pub enum RangedHealErrorCode {
1208    NotOwner = -1,
1209    Busy = -4,
1210    InvalidTarget = -7,
1211    NotInRange = -9,
1212    NoBodypart = -12,
1213}
1214
1215impl FromReturnCode for RangedHealErrorCode {
1216    type Error = Self;
1217
1218    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1219        let maybe_result = Self::try_result_from_i8(val);
1220        #[cfg(feature = "unsafe-return-conversion")]
1221        unsafe {
1222            maybe_result.unwrap_unchecked()
1223        }
1224        #[cfg(not(feature = "unsafe-return-conversion"))]
1225        maybe_result.unwrap()
1226    }
1227
1228    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1229        match val {
1230            0 => Some(Ok(())),
1231            -1 => Some(Err(RangedHealErrorCode::NotOwner)),
1232            -4 => Some(Err(RangedHealErrorCode::Busy)),
1233            -7 => Some(Err(RangedHealErrorCode::InvalidTarget)),
1234            -9 => Some(Err(RangedHealErrorCode::NotInRange)),
1235            -12 => Some(Err(RangedHealErrorCode::NoBodypart)),
1236            _ => None,
1237        }
1238    }
1239}
1240
1241impl fmt::Display for RangedHealErrorCode {
1242    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1243        let msg: &'static str = match self {
1244            RangedHealErrorCode::NotOwner => "you are not the owner of this creep",
1245            RangedHealErrorCode::Busy => "the creep is still being spawned",
1246            RangedHealErrorCode::InvalidTarget => "the target is not a valid creep object",
1247            RangedHealErrorCode::NotInRange => "the target is too far away",
1248            RangedHealErrorCode::NoBodypart => "there are no heal body parts in this creep’s body",
1249        };
1250
1251        write!(f, "{}", msg)
1252    }
1253}
1254
1255impl Error for RangedHealErrorCode {}
1256
1257impl From<RangedHealErrorCode> for ErrorCode {
1258    fn from(value: RangedHealErrorCode) -> Self {
1259        // Safety: RangedHealErrorCode is repr(i8), so we can cast it to get the
1260        // discriminant value, which will match the raw return code value that ErrorCode
1261        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1262        // Safety: RangedHealErrorCode discriminants are always error code values, and
1263        // thus the Result returned here will always be an `Err` variant, so we can
1264        // always extract the error without panicking
1265        Self::result_from_i8(value as i8).unwrap_err()
1266    }
1267}
1268
1269/// Error codes used by
1270/// [Creep::ranged_mass_attack](crate::Creep::ranged_mass_attack).
1271///
1272/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.rangedMassAttack).
1273///
1274/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L658)
1275#[derive(
1276    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1277)]
1278#[repr(i8)]
1279pub enum RangedMassAttackErrorCode {
1280    NotOwner = -1,
1281    Busy = -4,
1282    NoBodypart = -12,
1283}
1284
1285impl FromReturnCode for RangedMassAttackErrorCode {
1286    type Error = Self;
1287
1288    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1289        let maybe_result = Self::try_result_from_i8(val);
1290        #[cfg(feature = "unsafe-return-conversion")]
1291        unsafe {
1292            maybe_result.unwrap_unchecked()
1293        }
1294        #[cfg(not(feature = "unsafe-return-conversion"))]
1295        maybe_result.unwrap()
1296    }
1297
1298    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1299        match val {
1300            0 => Some(Ok(())),
1301            -1 => Some(Err(RangedMassAttackErrorCode::NotOwner)),
1302            -4 => Some(Err(RangedMassAttackErrorCode::Busy)),
1303            -12 => Some(Err(RangedMassAttackErrorCode::NoBodypart)),
1304            _ => None,
1305        }
1306    }
1307}
1308
1309impl fmt::Display for RangedMassAttackErrorCode {
1310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1311        let msg: &'static str = match self {
1312            RangedMassAttackErrorCode::NotOwner => "you are not the owner of this creep",
1313            RangedMassAttackErrorCode::Busy => "the creep is still being spawned",
1314            RangedMassAttackErrorCode::NoBodypart => {
1315                "there are no ranged_attack body parts in this creep’s body"
1316            }
1317        };
1318
1319        write!(f, "{}", msg)
1320    }
1321}
1322
1323impl Error for RangedMassAttackErrorCode {}
1324
1325impl From<RangedMassAttackErrorCode> for ErrorCode {
1326    fn from(value: RangedMassAttackErrorCode) -> Self {
1327        // Safety: RangedMassAttackErrorCode is repr(i8), so we can cast it to get the
1328        // discriminant value, which will match the raw return code value that ErrorCode
1329        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1330        // Safety: RangedMassAttackErrorCode discriminants are always error code values,
1331        // and thus the Result returned here will always be an `Err` variant, so we can
1332        // always extract the error without panicking
1333        Self::result_from_i8(value as i8).unwrap_err()
1334    }
1335}
1336
1337/// Error codes used by [Creep::repair](crate::Creep::repair).
1338///
1339/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.repair).
1340///
1341/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L734)
1342#[derive(
1343    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1344)]
1345#[repr(i8)]
1346pub enum CreepRepairErrorCode {
1347    NotOwner = -1,
1348    Busy = -4,
1349    NotEnoughResources = -6,
1350    InvalidTarget = -7,
1351    NotInRange = -9,
1352    NoBodypart = -12,
1353}
1354
1355impl FromReturnCode for CreepRepairErrorCode {
1356    type Error = Self;
1357
1358    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1359        let maybe_result = Self::try_result_from_i8(val);
1360        #[cfg(feature = "unsafe-return-conversion")]
1361        unsafe {
1362            maybe_result.unwrap_unchecked()
1363        }
1364        #[cfg(not(feature = "unsafe-return-conversion"))]
1365        maybe_result.unwrap()
1366    }
1367
1368    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1369        match val {
1370            0 => Some(Ok(())),
1371            -1 => Some(Err(CreepRepairErrorCode::NotOwner)),
1372            -4 => Some(Err(CreepRepairErrorCode::Busy)),
1373            -6 => Some(Err(CreepRepairErrorCode::NotEnoughResources)),
1374            -7 => Some(Err(CreepRepairErrorCode::InvalidTarget)),
1375            -9 => Some(Err(CreepRepairErrorCode::NotInRange)),
1376            -12 => Some(Err(CreepRepairErrorCode::NoBodypart)),
1377            _ => None,
1378        }
1379    }
1380}
1381
1382impl fmt::Display for CreepRepairErrorCode {
1383    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1384        let msg: &'static str = match self {
1385            CreepRepairErrorCode::NotOwner => "you are not the owner of this creep",
1386            CreepRepairErrorCode::Busy => "the creep is still being spawned",
1387            CreepRepairErrorCode::NotEnoughResources => "the creep does not carry any energy",
1388            CreepRepairErrorCode::InvalidTarget => "the target is not a valid structure object",
1389            CreepRepairErrorCode::NotInRange => "the target is too far away",
1390            CreepRepairErrorCode::NoBodypart => "there are no work body parts in this creep’s body",
1391        };
1392
1393        write!(f, "{}", msg)
1394    }
1395}
1396
1397impl Error for CreepRepairErrorCode {}
1398
1399impl From<CreepRepairErrorCode> for ErrorCode {
1400    fn from(value: CreepRepairErrorCode) -> Self {
1401        // Safety: CreepRepairErrorCode is repr(i8), so we can cast it to get the
1402        // discriminant value, which will match the raw return code value that ErrorCode
1403        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1404        // Safety: CreepRepairErrorCode discriminants are always error code values, and
1405        // thus the Result returned here will always be an `Err` variant, so we can
1406        // always extract the error without panicking
1407        Self::result_from_i8(value as i8).unwrap_err()
1408    }
1409}
1410
1411/// Error codes used by
1412/// [Creep::reserve_controller](crate::Creep::reserve_controller).
1413///
1414/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.reserveController).
1415///
1416/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L955)
1417#[derive(
1418    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1419)]
1420#[repr(i8)]
1421pub enum ReserveControllerErrorCode {
1422    NotOwner = -1,
1423    Busy = -4,
1424    InvalidTarget = -7,
1425    NotInRange = -9,
1426    NoBodypart = -12,
1427    AccessDenied = -16,
1428}
1429
1430impl FromReturnCode for ReserveControllerErrorCode {
1431    type Error = Self;
1432
1433    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1434        let maybe_result = Self::try_result_from_i8(val);
1435        #[cfg(feature = "unsafe-return-conversion")]
1436        unsafe {
1437            maybe_result.unwrap_unchecked()
1438        }
1439        #[cfg(not(feature = "unsafe-return-conversion"))]
1440        maybe_result.unwrap()
1441    }
1442
1443    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1444        match val {
1445            0 => Some(Ok(())),
1446            -1 => Some(Err(ReserveControllerErrorCode::NotOwner)),
1447            -4 => Some(Err(ReserveControllerErrorCode::Busy)),
1448            -7 => Some(Err(ReserveControllerErrorCode::InvalidTarget)),
1449            -9 => Some(Err(ReserveControllerErrorCode::NotInRange)),
1450            -12 => Some(Err(ReserveControllerErrorCode::NoBodypart)),
1451            -16 => Some(Err(ReserveControllerErrorCode::AccessDenied)),
1452            _ => None,
1453        }
1454    }
1455}
1456
1457impl fmt::Display for ReserveControllerErrorCode {
1458    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1459        let msg: &'static str = match self {
1460            ReserveControllerErrorCode::NotOwner => "you are not the owner of this creep",
1461            ReserveControllerErrorCode::Busy => "the creep is still being spawned",
1462            ReserveControllerErrorCode::InvalidTarget => {
1463                "the target is not a valid neutral controller object"
1464            }
1465            ReserveControllerErrorCode::NotInRange => "the target is too far away",
1466            ReserveControllerErrorCode::NoBodypart => {
1467                "there are no claim body parts in this creep’s body"
1468            }
1469            ReserveControllerErrorCode::AccessDenied => {
1470                "you do not have access to this restricted shard"
1471            }
1472        };
1473
1474        write!(f, "{}", msg)
1475    }
1476}
1477
1478impl Error for ReserveControllerErrorCode {}
1479
1480impl From<ReserveControllerErrorCode> for ErrorCode {
1481    fn from(value: ReserveControllerErrorCode) -> Self {
1482        // Safety: ReserveControllerErrorCode is repr(i8), so we can cast it to get the
1483        // discriminant value, which will match the raw return code value that ErrorCode
1484        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1485        // Safety: ReserveControllerErrorCode discriminants are always error code
1486        // values, and thus the Result returned here will always be an `Err` variant, so
1487        // we can always extract the error without panicking
1488        Self::result_from_i8(value as i8).unwrap_err()
1489    }
1490}
1491
1492/// Error codes used by [Creep::sign_controller](crate::Creep::sign_controller).
1493///
1494/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.signController).
1495///
1496/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L1072)
1497#[derive(
1498    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1499)]
1500#[repr(i8)]
1501pub enum SignControllerErrorCode {
1502    Busy = -4,
1503    InvalidTarget = -7,
1504    NotInRange = -9,
1505}
1506
1507impl FromReturnCode for SignControllerErrorCode {
1508    type Error = Self;
1509
1510    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1511        let maybe_result = Self::try_result_from_i8(val);
1512        #[cfg(feature = "unsafe-return-conversion")]
1513        unsafe {
1514            maybe_result.unwrap_unchecked()
1515        }
1516        #[cfg(not(feature = "unsafe-return-conversion"))]
1517        maybe_result.unwrap()
1518    }
1519
1520    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1521        match val {
1522            0 => Some(Ok(())),
1523            -4 => Some(Err(SignControllerErrorCode::Busy)),
1524            -7 => Some(Err(SignControllerErrorCode::InvalidTarget)),
1525            -9 => Some(Err(SignControllerErrorCode::NotInRange)),
1526            _ => None,
1527        }
1528    }
1529}
1530
1531impl fmt::Display for SignControllerErrorCode {
1532    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1533        let msg: &'static str = match self {
1534            SignControllerErrorCode::Busy => "the creep is still being spawned",
1535            SignControllerErrorCode::InvalidTarget => "the target is not a valid controller object",
1536            SignControllerErrorCode::NotInRange => "the target is too far away",
1537        };
1538
1539        write!(f, "{}", msg)
1540    }
1541}
1542
1543impl Error for SignControllerErrorCode {}
1544
1545impl From<SignControllerErrorCode> for ErrorCode {
1546    fn from(value: SignControllerErrorCode) -> Self {
1547        // Safety: SignControllerErrorCode is repr(i8), so we can cast it to get the
1548        // discriminant value, which will match the raw return code value that ErrorCode
1549        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1550        // Safety: SignControllerErrorCode discriminants are always error code values,
1551        // and thus the Result returned here will always be an `Err` variant, so we can
1552        // always extract the error without panicking
1553        Self::result_from_i8(value as i8).unwrap_err()
1554    }
1555}
1556
1557/// Error codes used by
1558/// [Creep::upgrade_controller](crate::Creep::upgrade_controller).
1559///
1560/// [Screeps API Docs](https://docs.screeps.com/api/#Creep.upgradeController).
1561///
1562/// [Screeps Engine Source Code](https://github.com/screeps/engine/blob/97c9d12385fed686655c13b09f5f2457dd83a2bf/src/game/creeps.js#L919)
1563#[derive(
1564    Debug, PartialEq, Eq, Clone, Copy, Hash, FromPrimitive, Deserialize_repr, Serialize_repr,
1565)]
1566#[repr(i8)]
1567pub enum UpgradeControllerErrorCode {
1568    NotOwner = -1,
1569    Busy = -4,
1570    NotEnoughResources = -6,
1571    InvalidTarget = -7,
1572    NotInRange = -9,
1573    NoBodypart = -12,
1574    AccessDenied = -16,
1575}
1576
1577impl FromReturnCode for UpgradeControllerErrorCode {
1578    type Error = Self;
1579
1580    fn result_from_i8(val: i8) -> Result<(), Self::Error> {
1581        let maybe_result = Self::try_result_from_i8(val);
1582        #[cfg(feature = "unsafe-return-conversion")]
1583        unsafe {
1584            maybe_result.unwrap_unchecked()
1585        }
1586        #[cfg(not(feature = "unsafe-return-conversion"))]
1587        maybe_result.unwrap()
1588    }
1589
1590    fn try_result_from_i8(val: i8) -> Option<Result<(), Self::Error>> {
1591        match val {
1592            0 => Some(Ok(())),
1593            -1 => Some(Err(UpgradeControllerErrorCode::NotOwner)),
1594            -4 => Some(Err(UpgradeControllerErrorCode::Busy)),
1595            -6 => Some(Err(UpgradeControllerErrorCode::NotEnoughResources)),
1596            -7 => Some(Err(UpgradeControllerErrorCode::InvalidTarget)),
1597            -9 => Some(Err(UpgradeControllerErrorCode::NotInRange)),
1598            -12 => Some(Err(UpgradeControllerErrorCode::NoBodypart)),
1599            -16 => Some(Err(UpgradeControllerErrorCode::AccessDenied)),
1600            _ => None,
1601        }
1602    }
1603}
1604
1605impl fmt::Display for UpgradeControllerErrorCode {
1606    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1607        let msg: &'static str = match self {
1608            UpgradeControllerErrorCode::NotOwner => "you are not the owner of this creep or the target controller",
1609            UpgradeControllerErrorCode::Busy => "the creep is still being spawned",
1610            UpgradeControllerErrorCode::NotEnoughResources => "the creep does not have any carried energy",
1611            UpgradeControllerErrorCode::InvalidTarget => "the target is not a valid controller object, or the controller upgrading is blocked",
1612            UpgradeControllerErrorCode::NotInRange => "the target is too far away",
1613            UpgradeControllerErrorCode::NoBodypart => "there are no work body parts in this creep’s body",
1614            UpgradeControllerErrorCode::AccessDenied => "you do not have access to this restricted shard",
1615        };
1616
1617        write!(f, "{}", msg)
1618    }
1619}
1620
1621impl Error for UpgradeControllerErrorCode {}
1622
1623impl From<UpgradeControllerErrorCode> for ErrorCode {
1624    fn from(value: UpgradeControllerErrorCode) -> Self {
1625        // Safety: UpgradeControllerErrorCode is repr(i8), so we can cast it to get the
1626        // discriminant value, which will match the raw return code value that ErrorCode
1627        // expects.   Ref: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.intro
1628        // Safety: UpgradeControllerErrorCode discriminants are always error code
1629        // values, and thus the Result returned here will always be an `Err` variant, so
1630        // we can always extract the error without panicking
1631        Self::result_from_i8(value as i8).unwrap_err()
1632    }
1633}