1use indexmap::IndexMap;
4#[cfg(feature = "serialization")]
5use serde::{Deserialize, Serialize};
6use std::fmt::Debug;
7use std::hash::Hash;
8
9pub trait Id {
11 #[cfg(not(feature = "serialization"))]
12 type Id: Hash + Eq + Clone + Debug + Send;
14 #[cfg(feature = "serialization")]
15 type Id: Hash + Eq + Clone + Debug + Send + Serialize + for<'a> Deserialize<'a>;
17
18 fn id(&self) -> &Self::Id;
20}
21
22pub(crate) fn collect_from_iter<I>(
25 it: I,
26) -> IndexMap<<<I as Iterator>::Item as Id>::Id, <I as Iterator>::Item>
27where
28 I: Iterator,
29 <I as Iterator>::Item: Id,
30{
31 let mut map = IndexMap::new();
32 for e in it {
33 if !map.contains_key(e.id()) {
34 map.insert(e.id().clone(), e);
35 }
36 }
37 map
38}
39
40#[cfg(test)]
42pub(crate) mod tests {
43 use crate::battle::{Battle, BattleRules};
44 use crate::creature::{CreateCreature, CreatureId};
45 use crate::event::{DefaultOutput, DummyEvent, EventProcessor, EventTrigger};
46 use crate::object::{CreateObject, ObjectId};
47 use crate::server::Server;
48 use crate::space::Position;
49 use crate::team::{CreateTeam, TeamId};
50
51 pub(crate) fn server<R: BattleRules + 'static>(rules: R) -> Server<R> {
52 let battle = Battle::builder(rules).build();
53 Server::builder(battle).build()
54 }
55
56 pub(crate) fn team<'a, R: BattleRules + 'static>(server: &'a mut Server<R>, id: TeamId<R>) {
58 assert_eq!(CreateTeam::trigger(server, id).fire().err(), None);
59 }
60
61 pub(crate) fn creature<'a, R: BattleRules + 'static>(
63 server: &'a mut Server<R>,
64 creature_id: CreatureId<R>,
65 team_id: TeamId<R>,
66 position: Position<R>,
67 ) {
68 assert_eq!(
69 CreateCreature::trigger(server, creature_id, team_id, position)
70 .fire()
71 .err(),
72 None
73 );
74 }
75
76 pub(crate) fn object<'a, R: BattleRules + 'static>(
78 server: &'a mut Server<R>,
79 object_id: ObjectId<R>,
80 position: Position<R>,
81 ) {
82 assert_eq!(
83 CreateObject::trigger(server, object_id, position)
84 .fire()
85 .err(),
86 None
87 );
88 }
89
90 pub(crate) fn dummy<R, P>(processor: &mut P)
92 where
93 R: BattleRules + 'static,
94 P: EventProcessor<R>,
95 {
96 assert_eq!(DummyEvent::trigger(processor).fire().err(), None);
97 }
98}