1use crate::{fallible_try_from, fallible_try_into, infallible_try_into};
2use std::convert::{TryFrom, TryInto};
3use std::fmt;
4use std::num::TryFromIntError;
5
6#[derive(Debug, Hash, Default, Clone, Copy, PartialEq, Eq)]
8pub struct UnitTypeID(u16);
9
10impl From<u16> for UnitTypeID {
11 #[inline]
12 fn from(n: u16) -> Self {
13 UnitTypeID(n)
14 }
15}
16
17impl From<UnitTypeID> for u16 {
18 #[inline]
19 fn from(n: UnitTypeID) -> Self {
20 n.0
21 }
22}
23
24impl From<UnitTypeID> for i32 {
25 #[inline]
26 fn from(n: UnitTypeID) -> Self {
27 n.0.into()
28 }
29}
30
31impl From<UnitTypeID> for u32 {
32 #[inline]
33 fn from(n: UnitTypeID) -> Self {
34 n.0.into()
35 }
36}
37
38impl From<UnitTypeID> for usize {
39 #[inline]
40 fn from(n: UnitTypeID) -> Self {
41 n.0.into()
42 }
43}
44
45fallible_try_into!(UnitTypeID, i16);
46fallible_try_from!(UnitTypeID, i16);
47fallible_try_from!(UnitTypeID, i32);
48fallible_try_from!(UnitTypeID, u32);
49
50#[derive(Debug, Hash, Default, Clone, Copy, PartialEq, Eq)]
52pub struct TechID(u16);
53
54impl From<u16> for TechID {
55 fn from(n: u16) -> Self {
56 TechID(n)
57 }
58}
59
60impl From<TechID> for u16 {
61 fn from(n: TechID) -> Self {
62 n.0
63 }
64}
65
66impl From<TechID> for usize {
67 fn from(n: TechID) -> Self {
68 n.0.into()
69 }
70}
71
72fallible_try_into!(TechID, i16);
73infallible_try_into!(TechID, u32);
74fallible_try_from!(TechID, i32);
75fallible_try_from!(TechID, u32);
76
77#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
79pub struct SpriteID(u16);
80impl From<u16> for SpriteID {
81 fn from(n: u16) -> Self {
82 SpriteID(n)
83 }
84}
85
86impl From<SpriteID> for u16 {
87 fn from(n: SpriteID) -> Self {
88 n.0
89 }
90}
91
92impl From<SpriteID> for i32 {
93 fn from(n: SpriteID) -> Self {
94 n.0.into()
95 }
96}
97
98impl From<SpriteID> for u32 {
99 fn from(n: SpriteID) -> Self {
100 n.0.into()
101 }
102}
103
104impl From<SpriteID> for usize {
105 fn from(n: SpriteID) -> Self {
106 n.0.into()
107 }
108}
109
110fallible_try_into!(SpriteID, i16);
111fallible_try_from!(SpriteID, i16);
112fallible_try_from!(SpriteID, i32);
113fallible_try_from!(SpriteID, u32);
114
115#[derive(Debug, Hash, Clone, PartialEq, Eq)]
123pub enum StringKey {
124 Num(u32),
126
127 Name(String),
130}
131
132impl Default for StringKey {
133 #[inline]
134 fn default() -> Self {
135 Self::Num(0)
136 }
137}
138
139impl StringKey {
140 #[inline]
151 pub fn is_numeric(&self) -> bool {
152 match self {
153 Self::Num(_) => true,
154 Self::Name(_) => false,
155 }
156 }
157
158 #[inline]
169 pub fn is_named(&self) -> bool {
170 match self {
171 Self::Num(_) => false,
172 Self::Name(_) => true,
173 }
174 }
175}
176
177impl fmt::Display for StringKey {
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 match self {
180 Self::Num(n) => write!(f, "{}", n),
181 Self::Name(s) => write!(f, "{}", s),
182 }
183 }
184}
185
186impl From<u32> for StringKey {
187 #[inline]
188 fn from(n: u32) -> Self {
189 Self::Num(n)
190 }
191}
192
193impl From<u16> for StringKey {
194 #[inline]
195 fn from(n: u16) -> Self {
196 Self::Num(n.into())
197 }
198}
199
200impl TryFrom<i32> for StringKey {
201 type Error = TryFromIntError;
202 #[inline]
203 fn try_from(n: i32) -> Result<Self, Self::Error> {
204 u32::try_from(n).map(Self::Num)
205 }
206}
207
208impl TryFrom<i16> for StringKey {
209 type Error = TryFromIntError;
210 #[inline]
211 fn try_from(n: i16) -> Result<Self, Self::Error> {
212 u32::try_from(n).map(Self::Num)
213 }
214}
215
216impl From<&str> for StringKey {
217 #[inline]
218 fn from(s: &str) -> Self {
219 if let Ok(n) = s.parse() {
220 Self::Num(n)
221 } else {
222 Self::Name(String::from(s))
223 }
224 }
225}
226
227impl From<String> for StringKey {
228 #[inline]
229 fn from(s: String) -> Self {
230 Self::from(s.as_ref())
231 }
232}
233
234#[derive(Debug, Clone, thiserror::Error)]
243#[error("could not convert StringKey to the wanted integer size")]
244pub struct TryFromStringKeyError;
245
246macro_rules! try_from_string_key {
248 ($type:ty) => {
249 impl TryFrom<&StringKey> for $type {
250 type Error = TryFromStringKeyError;
251 #[inline]
252 fn try_from(key: &StringKey) -> Result<Self, Self::Error> {
253 match key {
254 StringKey::Num(n) => (*n).try_into().map_err(|_| TryFromStringKeyError),
255 _ => Err(TryFromStringKeyError),
256 }
257 }
258 }
259 };
260}
261
262try_from_string_key!(u32);
263try_from_string_key!(i32);
264try_from_string_key!(u16);
265try_from_string_key!(i16);
266
267#[cfg(test)]
268mod tests {
269 use super::*;
270
271 #[test]
273 fn string_key_from_int() {
274 if let StringKey::Num(n) = StringKey::try_from(0).unwrap() {
275 assert_eq!(0, n);
276 } else {
277 panic!();
278 }
279 }
280
281 #[test]
283 fn string_key_from_str_to_int() {
284 let s = "57329";
285 if let StringKey::Num(n) = StringKey::from(s) {
286 assert_eq!(57329, n);
287 } else {
288 panic!();
289 }
290 }
291
292 #[test]
294 fn string_key_from_str_to_str() {
295 let s = "grassDaut";
296 if let StringKey::Name(n) = StringKey::from(s) {
297 assert_eq!(s, n);
298 } else {
299 panic!();
300 }
301 }
302}