weasel/
util.rs

1//! Collection of utilities.
2
3use indexmap::IndexMap;
4#[cfg(feature = "serialization")]
5use serde::{Deserialize, Serialize};
6use std::fmt::Debug;
7use std::hash::Hash;
8
9/// Trait for an object that can provide an Id for itself.
10pub trait Id {
11    #[cfg(not(feature = "serialization"))]
12    /// Type of the id value.
13    type Id: Hash + Eq + Clone + Debug + Send;
14    #[cfg(feature = "serialization")]
15    /// Type of the id value.
16    type Id: Hash + Eq + Clone + Debug + Send + Serialize + for<'a> Deserialize<'a>;
17
18    /// Returns a reference to the current id.
19    fn id(&self) -> &Self::Id;
20}
21
22/// Collects an iterator into an indexmap.
23/// Subsequent values with same key are ignored.
24pub(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/// Creates a server from the given battlerules.
41#[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    /// Creates a team with default arguments.
57    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    /// Creates a creature with default arguments.
62    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    /// Creates an object with default arguments.
77    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    /// Dummy event.
91    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}