1use crate::error::{Error, Result};
5use crate::ethic::Ethics;
6use crate::resources::Resources;
7use derive_more::{Display, From, Into};
8use serde::{Deserialize, Serialize};
9use std::borrow::{Borrow, Cow};
10use std::collections::HashMap;
11use std::ops::Deref;
12use std::sync::Arc;
13
14#[derive(Clone, Debug, Default, Deserialize, Serialize)]
15#[serde(rename_all = "camelCase")]
16pub struct BotManager(HashMap<BotId, Bot>);
17
18impl BotManager {
19 pub(crate) fn manage(&mut self, id: BotId) -> Result<()> {
20 if self.0.contains_key(&id) {
21 return Err(Error::BotAlreadySpawned(id));
22 }
23
24 self.0.insert(id.clone(), Bot::new(id));
25
26 Ok(())
27 }
28
29 pub fn bot(&self, id: &BotId) -> Result<&Bot> {
30 self
31 .0
32 .get(id)
33 .ok_or_else(|| Error::BotNotFound(id.clone()))
34 }
35
36 pub(crate) fn bot_mut(&mut self, id: &BotId) -> Result<&mut Bot> {
37 self
38 .0
39 .get_mut(id)
40 .ok_or_else(|| Error::BotNotFound(id.clone()))
41 }
42
43 pub fn bots(&self) -> impl Iterator<Item = &Bot> {
44 self.0.values()
45 }
46}
47
48#[derive(Clone, Debug, Deserialize, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub struct Bot {
51 id: BotId,
52 ethics: Ethics,
53 resources: Resources,
54}
55
56impl Bot {
57 pub(crate) fn new(id: BotId) -> Self {
58 Self {
59 id,
60 ethics: Ethics::random(),
61 resources: Resources::BOT.clone(),
62 }
63 }
64
65 #[inline]
66 pub fn id(&self) -> BotId {
67 self.id.clone()
68 }
69
70 #[inline]
71 pub fn ethics(&self) -> &Ethics {
72 &self.ethics
73 }
74
75 #[inline]
76 pub(crate) fn ethics_mut(&mut self) -> &mut Ethics {
77 &mut self.ethics
78 }
79
80 #[inline]
81 pub fn resources(&self) -> &Resources {
82 &self.resources
83 }
84
85 pub(crate) fn resources_mut(&mut self) -> &mut Resources {
86 &mut self.resources
87 }
88}
89
90#[derive(Debug, Display, PartialEq, Eq, Hash, From, Into, Deserialize, Serialize)]
91#[from(String, &str, Arc<str>, Box<str>, Cow<'_, str>)]
92pub struct BotId(Arc<str>);
93
94impl Clone for BotId {
95 fn clone(&self) -> Self {
96 Self(Arc::clone(&self.0))
97 }
98}
99
100impl AsRef<str> for BotId {
101 fn as_ref(&self) -> &str {
102 self.0.as_str()
103 }
104}
105
106impl Deref for BotId {
107 type Target = str;
108
109 fn deref(&self) -> &Self::Target {
110 self.0.as_str()
111 }
112}
113
114impl Borrow<str> for BotId {
115 fn borrow(&self) -> &str {
116 self.0.as_str()
117 }
118}
119
120impl From<BotId> for String {
121 fn from(value: BotId) -> Self {
122 String::from(value.0.as_ref())
123 }
124}
125
126#[derive(Clone, Debug, Deserialize, Serialize)]
127#[serde(rename_all = "camelCase")]
128pub struct PublicBot {
129 id: BotId,
130}
131
132impl From<&Bot> for PublicBot {
133 fn from(bot: &Bot) -> Self {
134 Self { id: bot.id.clone() }
135 }
136}