1use crate::ethic::Ethics;
5use crate::npc::bot::{Bot, BotId};
6use crate::npc::precursor::{Precursor, PrecursorId};
7use crate::player::{Player, PlayerId};
8use crate::resources::Resources;
9use crate::resources::influence::Influence;
10use derive_more::{TryUnwrap, Unwrap};
11use serde::{Deserialize, Serialize};
12use std::{fmt, mem};
13use strum::EnumIs;
14
15#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, EnumIs)]
16#[serde(tag = "kind", rename_all = "kebab-case")]
17#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
18pub enum Ruler {
19 Bot { id: BotId },
20 Player { id: PlayerId },
21 Precursor { id: PrecursorId },
22}
23
24impl Ruler {
25 #[inline]
26 pub fn bot(&self) -> Option<&BotId> {
27 if let Self::Bot { id } = self { Some(id) } else { None }
28 }
29
30 #[inline]
31 pub fn player(&self) -> Option<&PlayerId> {
32 if let Self::Player { id } = self { Some(id) } else { None }
33 }
34
35 #[inline]
36 pub fn precursor(&self) -> Option<PrecursorId> {
37 if let Self::Precursor { id } = self { Some(*id) } else { None }
38 }
39
40 pub fn is_bot_and<F>(&self, f: F) -> bool
41 where
42 F: FnOnce(&BotId) -> bool,
43 {
44 self.bot().is_some_and(f)
45 }
46
47 pub fn is_player_and<F>(&self, f: F) -> bool
48 where
49 F: FnOnce(&PlayerId) -> bool,
50 {
51 self.player().is_some_and(f)
52 }
53
54 pub fn is_precursor_and<F>(&self, f: F) -> bool
55 where
56 F: FnOnce(PrecursorId) -> bool,
57 {
58 self.precursor().is_some_and(f)
59 }
60}
61
62impl AsRef<str> for Ruler {
63 fn as_ref(&self) -> &str {
64 match self {
65 Self::Bot { id } => id.as_str(),
66 Self::Player { id } => id.as_str(),
67 Self::Precursor { id } => id.as_ref(),
68 }
69 }
70}
71
72impl fmt::Display for Ruler {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match self {
75 Self::Bot { id } => id.fmt(f),
76 Self::Player { id } => id.fmt(f),
77 Self::Precursor { id } => id.fmt(f),
78 }
79 }
80}
81
82impl From<&Bot> for Ruler {
83 fn from(bot: &Bot) -> Self {
84 Self::Bot { id: bot.id() }
85 }
86}
87
88impl From<BotId> for Ruler {
89 fn from(id: BotId) -> Self {
90 Self::Bot { id }
91 }
92}
93
94impl From<&BotId> for Ruler {
95 fn from(id: &BotId) -> Self {
96 Self::Bot { id: id.clone() }
97 }
98}
99
100impl From<&Player> for Ruler {
101 fn from(player: &Player) -> Self {
102 Self::Player { id: player.id() }
103 }
104}
105
106impl From<PlayerId> for Ruler {
107 fn from(id: PlayerId) -> Self {
108 Self::Player { id }
109 }
110}
111
112impl From<&PlayerId> for Ruler {
113 fn from(id: &PlayerId) -> Self {
114 Self::Player { id: id.clone() }
115 }
116}
117
118impl From<&dyn Precursor> for Ruler {
119 fn from(precursor: &dyn Precursor) -> Self {
120 Self::Precursor { id: precursor.id() }
121 }
122}
123
124impl<T: Precursor> From<&T> for Ruler {
125 fn from(precursor: &T) -> Self {
126 Self::Precursor { id: precursor.id() }
127 }
128}
129
130impl From<PrecursorId> for Ruler {
131 fn from(id: PrecursorId) -> Self {
132 Self::Precursor { id }
133 }
134}
135
136impl From<RulerRef<'_>> for Ruler {
137 fn from(ruler: RulerRef<'_>) -> Self {
138 match ruler {
139 RulerRef::Bot(bot) => Self::Bot { id: bot.id() },
140 RulerRef::Player(player) => Self::Player { id: player.id() },
141 RulerRef::Precursor(precursor) => Self::Precursor { id: precursor.id() },
142 }
143 }
144}
145
146impl From<RulerRefMut<'_>> for Ruler {
147 fn from(ruler: RulerRefMut<'_>) -> Self {
148 match ruler {
149 RulerRefMut::Bot(bot) => Self::Bot { id: bot.id() },
150 RulerRefMut::Player(player) => Self::Player { id: player.id() },
151 RulerRefMut::Precursor(precursor) => Self::Precursor { id: precursor.id() },
152 }
153 }
154}
155
156#[derive(EnumIs, TryUnwrap, Unwrap)]
157#[try_unwrap(ref)]
158#[unwrap(ref)]
159pub enum RulerRef<'a> {
160 Bot(&'a Bot),
161 Player(&'a Player),
162 Precursor(&'a dyn Precursor),
163}
164
165impl<'a> RulerRef<'a> {
166 pub fn ethics(&self) -> Option<&'a Ethics> {
167 match self {
168 Self::Bot(bot) => Some(bot.ethics()),
169 Self::Player(..) => None,
170 Self::Precursor(precursor) => Some(precursor.ethics()),
171 }
172 }
173
174 pub fn resources(&'a self) -> &'a Resources {
175 match self {
176 Self::Bot(bot) => bot.resources(),
177 Self::Player(player) => player.resources(),
178 Self::Precursor(precursor) => precursor.resources(),
179 }
180 }
181
182 #[inline]
183 pub fn has_resources(&self, resources: &Resources) -> bool {
184 self
185 .resources()
186 .checked_sub(resources)
187 .is_some()
188 }
189
190 pub fn influence(&self) -> Influence {
191 match self {
192 Self::Bot(bot) => bot.influence(),
193 Self::Player(player) => player.influence(),
194 Self::Precursor(precursor) => precursor.influence(),
195 }
196 }
197}
198
199impl<'a> From<&'a Bot> for RulerRef<'a> {
200 fn from(bot: &'a Bot) -> Self {
201 Self::Bot(bot)
202 }
203}
204
205impl<'a> From<&'a Player> for RulerRef<'a> {
206 fn from(player: &'a Player) -> Self {
207 Self::Player(player)
208 }
209}
210
211impl<'a> From<&'a dyn Precursor> for RulerRef<'a> {
212 fn from(precursor: &'a dyn Precursor) -> Self {
213 Self::Precursor(precursor)
214 }
215}
216
217#[derive(EnumIs, TryUnwrap, Unwrap)]
218#[try_unwrap(ref)]
219#[unwrap(ref)]
220pub enum RulerRefMut<'a> {
221 Bot(&'a mut Bot),
222 Player(&'a mut Player),
223 Precursor(&'a mut dyn Precursor),
224}
225
226impl<'a> RulerRefMut<'a> {
227 pub fn resources_mut(&'a mut self) -> &'a mut Resources {
228 match self {
229 Self::Bot(bot) => bot.resources_mut(),
230 Self::Player(player) => player.resources_mut(),
231 Self::Precursor(precursor) => precursor.resources_mut(),
232 }
233 }
234
235 pub fn take_resources(&mut self) -> Resources {
236 match self {
237 Self::Bot(bot) => mem::take(bot.resources_mut()),
238 Self::Player(player) => mem::take(player.resources_mut()),
239 Self::Precursor(precursor) => mem::take(precursor.resources_mut()),
240 }
241 }
242}
243
244impl<'a> From<&'a mut Bot> for RulerRefMut<'a> {
245 fn from(bot: &'a mut Bot) -> Self {
246 Self::Bot(bot)
247 }
248}
249
250impl<'a> From<&'a mut Player> for RulerRefMut<'a> {
251 fn from(player: &'a mut Player) -> Self {
252 Self::Player(player)
253 }
254}
255
256impl<'a> From<&'a mut dyn Precursor> for RulerRefMut<'a> {
257 fn from(precursor: &'a mut dyn Precursor) -> Self {
258 Self::Precursor(precursor)
259 }
260}