belief_spread/
behaviour.rs

1use by_address::ByAddress;
2use core::fmt::Debug;
3use std::{cell::RefCell, rc::Rc};
4use uuid::Uuid;
5
6use crate::{Named, UUIDd};
7
8/// A Behaviour.
9pub trait Behaviour: UUIDd + Named + Debug {}
10
11/// A [Rc] [RefCell] pointer to [Behaviour] compared by address.
12pub type BehaviourPtr = ByAddress<Rc<RefCell<dyn Behaviour>>>;
13
14impl From<BasicBehaviour> for BehaviourPtr {
15    /// Convert from a [BasicBehaviour] into a [BehaviourPtr].
16    ///
17    /// This consumes the [BasicBehaviour].
18    ///
19    /// # Arguments
20    /// - `b`: The [BasicBehaviour] to convert.
21    ///
22    /// # Returns
23    /// The [BehaviourPtr].
24    ///
25    /// # Examples
26    /// ```
27    /// use belief_spread::{BasicBehaviour, BehaviourPtr};
28    ///
29    /// let b = BasicBehaviour::new("Behaviour 1".to_string());
30    /// let b_ptr = BehaviourPtr::from(b);
31    /// ```
32    ///
33    /// ```
34    /// use belief_spread::{BasicBehaviour, BehaviourPtr};
35    ///
36    /// let b = BasicBehaviour::new("Behaviour 1".to_string());
37    /// let b_ptr: BehaviourPtr = b.into();
38    /// ```
39    fn from(b: BasicBehaviour) -> Self {
40        ByAddress(Rc::new(RefCell::new(b)))
41    }
42}
43
44/// A BasicBehaviour is an implementation of a [Behaviour].
45#[derive(Debug)]
46pub struct BasicBehaviour {
47    /// The name of the [BasicBehaviour]
48    name: String,
49    /// The [Uuid] of the [BasicBehaviour].
50    uuid: Uuid,
51}
52
53impl BasicBehaviour {
54    /// Create a new [BasicBehaviour] with random [Uuid].
55    ///
56    /// # Arguments
57    /// - `name`: The name of the [BasicBehaviour].
58    ///
59    /// # Returns
60    /// The new [BasicBehaviour] with a [Uuid] generated using
61    /// [`uuid::Uuid::new_v4`].
62    ///
63    /// # Examples
64    ///
65    /// ```
66    /// use belief_spread::BasicBehaviour;
67    ///
68    /// let b = BasicBehaviour::new("Behaviour 1".to_string());
69    /// ```
70    pub fn new(name: String) -> BasicBehaviour {
71        Self::new_with_uuid(name, Uuid::new_v4())
72    }
73
74    /// Create a new [BasicBehaviour] with specified [Uuid].
75    ///
76    /// # Arguments
77    /// - `name`: The name of the [BasicBehaviour].
78    /// - `uuid`: The [Uuid] of the [BasicBehaviour].
79    ///
80    /// # Returns
81    /// The new [BasicBehaviour].
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use belief_spread::BasicBehaviour;
87    /// use uuid::Uuid;
88    ///
89    /// let b = BasicBehaviour::new_with_uuid("Behaviour 1".to_string(), Uuid::new_v4());
90    /// ```
91    pub fn new_with_uuid(name: String, uuid: Uuid) -> BasicBehaviour {
92        BasicBehaviour { name, uuid }
93    }
94}
95
96impl Behaviour for BasicBehaviour {}
97
98impl Named for BasicBehaviour {
99    /// Get the name of the [BasicBehaviour].
100    fn name(&self) -> &str {
101        &self.name
102    }
103
104    /// Set the name of the [BasicBehaviour].
105    fn set_name(&mut self, name: String) {
106        self.name = name
107    }
108}
109
110impl UUIDd for BasicBehaviour {
111    /// Get the [Uuid] of the [BasicBehaviour].
112    fn uuid(&self) -> &Uuid {
113        &self.uuid
114    }
115
116    /// Set the [Uuid] of the [BasicBehaviour].
117    fn set_uuid(&mut self, u: Uuid) {
118        self.uuid = u
119    }
120}
121
122impl PartialEq for BasicBehaviour {
123    /// Check whether two [BasicBehaviour]s are equal based solely on their
124    /// [Uuid].
125    fn eq(&self, other: &Self) -> bool {
126        self.uuid == other.uuid
127    }
128}
129
130impl Eq for BasicBehaviour {}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn new_assigns_random_uuid() {
138        let b1 = BasicBehaviour::new("b1".to_string());
139        let b2 = BasicBehaviour::new("b2".to_string());
140        assert_ne!(b1.uuid(), b2.uuid());
141    }
142
143    #[test]
144    fn new_assigns_name() {
145        let b1 = BasicBehaviour::new("b1".to_string());
146        assert_eq!(b1.name(), "b1");
147    }
148
149    #[test]
150    fn new_with_uuid_assigns_uuid() {
151        let uuid = Uuid::new_v4();
152        let b1 = BasicBehaviour::new_with_uuid("b1".to_string(), uuid.clone());
153        assert_eq!(b1.uuid(), &uuid);
154    }
155
156    #[test]
157    fn new_with_uuid_assigns_name() {
158        let uuid = Uuid::new_v4();
159        let b1 = BasicBehaviour::new_with_uuid("b1".to_string(), uuid.clone());
160        assert_eq!(b1.name(), "b1");
161    }
162
163    #[test]
164    fn uuid_returns_uuid() {
165        let uuid = Uuid::new_v4();
166        let b = BasicBehaviour::new_with_uuid("b".to_string(), uuid.clone());
167        assert_eq!(b.uuid(), &uuid);
168    }
169
170    #[test]
171    fn set_uuid_sets_uuid() {
172        let uuid = Uuid::new_v4();
173        let mut b = BasicBehaviour::new_with_uuid("b".to_string(), uuid.clone());
174        assert_eq!(b.uuid(), &uuid);
175        let uuid2 = Uuid::new_v4();
176        b.set_uuid(uuid2);
177        assert_eq!(b.uuid(), &uuid2);
178    }
179
180    #[test]
181    fn name_returns_name() {
182        let b = BasicBehaviour::new("b".to_string());
183        assert_eq!(b.name(), "b");
184    }
185
186    #[test]
187    fn set_name_sets_name() {
188        let mut b = BasicBehaviour::new("b".to_string());
189        assert_eq!(b.name(), "b");
190        b.set_name("bb".to_string());
191        assert_eq!(b.name(), "bb");
192    }
193
194    #[test]
195    fn test_equals_when_uuids_match_but_name_doesnt() {
196        let uuid = Uuid::new_v4();
197        let b1 = BasicBehaviour::new_with_uuid("b1".to_string(), uuid);
198        let b2 = BasicBehaviour::new_with_uuid("b2".to_string(), uuid);
199        assert_eq!(b1, b2)
200    }
201
202    #[test]
203    fn test_equals_when_uuids_dont_match() {
204        let uuid = Uuid::new_v4();
205        let b1 = BasicBehaviour::new_with_uuid("b1".to_string(), uuid);
206        let b2 = BasicBehaviour::new_with_uuid("b2".to_string(), Uuid::new_v4());
207        assert_ne!(b1, b2)
208    }
209
210    #[test]
211    fn test_from() {
212        let b = BasicBehaviour::new("b1".to_string());
213        let b_ptr: BehaviourPtr = BehaviourPtr::from(b);
214        assert_eq!(b_ptr.borrow().name(), "b1");
215    }
216
217    #[test]
218    fn test_into() {
219        let b = BasicBehaviour::new("b1".to_string());
220        let b_ptr: BehaviourPtr = b.into();
221        assert_eq!(b_ptr.borrow().name(), "b1");
222    }
223}