1use std::collections::VecDeque;
10
11use crate::types::{ActorId, MsgId, PluginId, SecurityLevel};
12
13pub type Queue<T> = VecDeque<T>;
19
20#[derive(Debug)]
22pub enum ActorError {
23 MailboxFull(usize, usize),
25 NoMessage,
27 Blocked(ActorId),
29}
30
31pub type Data = Vec<u8>;
37
38#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct Message {
43 pub(crate) id: MsgId,
47
48 pub(crate) src: PluginId,
52
53 pub(crate) dst: PluginId,
57
58 pub(crate) level: SecurityLevel,
62
63 pub(crate) body: Data,
67}
68
69impl Message {
70 pub fn new(id: MsgId, src: PluginId, dst: PluginId, level: SecurityLevel, body: Data) -> Self {
72 Message {
73 id,
74 src,
75 dst,
76 level,
77 body,
78 }
79 }
80
81 #[inline]
83 pub fn id(&self) -> MsgId {
84 self.id
85 }
86
87 #[inline]
89 pub fn src(&self) -> PluginId {
90 self.src
91 }
92
93 #[inline]
95 pub fn dst(&self) -> PluginId {
96 self.dst
97 }
98
99 #[inline]
101 pub fn level(&self) -> SecurityLevel {
102 self.level
103 }
104
105 #[inline]
107 pub fn body(&self) -> &Data {
108 &self.body
109 }
110
111 pub fn into_body(self) -> Data {
113 self.body
114 }
115}
116
117#[derive(Debug, Clone)]
121pub struct ActorRuntime {
122 pub(crate) pending: Queue<Message>,
126
127 pub(crate) mailbox: Queue<Message>,
131
132 pub(crate) capacity: usize,
136
137 pub(crate) blocked_on: Option<ActorId>,
141
142 pub(crate) pending_send: Option<Message>,
146}
147
148impl ActorRuntime {
149 pub fn empty(capacity: usize) -> Self {
153 ActorRuntime {
154 pending: VecDeque::new(),
155 mailbox: VecDeque::new(),
156 capacity,
157 blocked_on: None,
158 pending_send: None,
159 }
160 }
161
162 #[inline]
166 pub fn can_receive(&self) -> bool {
167 !self.mailbox.is_empty()
168 }
169
170 #[inline]
174 pub fn can_send(&self, target_capacity: usize) -> bool {
175 self.pending.len() < target_capacity
176 }
177
178 #[inline]
182 pub fn mailbox_has_space(&self) -> bool {
183 self.mailbox.len() < self.capacity
184 }
185
186 pub fn enqueue_pending(&self, msg: Message) -> Self {
190 let mut new_pending = self.pending.clone();
191 new_pending.push_back(msg);
192 ActorRuntime {
193 pending: new_pending,
194 mailbox: self.mailbox.clone(),
195 capacity: self.capacity,
196 blocked_on: self.blocked_on,
197 pending_send: self.pending_send.clone(),
198 }
199 }
200
201 pub fn enqueue_pending_mut(&mut self, msg: Message) {
203 self.pending.push_back(msg);
204 }
205
206 pub fn deliver(&self) -> Self {
213 if self.pending.is_empty() {
215 return self.clone();
216 }
217 if self.mailbox.len() >= self.capacity {
219 return self.clone();
220 }
221
222 let mut new_pending = self.pending.clone();
224 let first_msg = new_pending.pop_front().expect("checked non-empty");
225 let mut new_mailbox = self.mailbox.clone();
226 new_mailbox.push_back(first_msg);
227
228 ActorRuntime {
229 pending: new_pending,
230 mailbox: new_mailbox,
231 capacity: self.capacity,
232 blocked_on: self.blocked_on,
233 pending_send: self.pending_send.clone(),
234 }
235 }
236
237 pub fn deliver_mut(&mut self) -> Result<bool, ActorError> {
245 if self.pending.is_empty() {
246 return Err(ActorError::NoMessage);
247 }
248
249 if self.mailbox.len() < self.capacity {
250 let msg = self.pending.pop_front().expect("checked non-empty");
251 self.mailbox.push_back(msg);
252 Ok(true)
253 } else {
254 Ok(false)
256 }
257 }
258
259 pub fn consume(&self) -> (Self, Option<Message>) {
265 if self.mailbox.is_empty() {
266 return (self.clone(), None);
267 }
268
269 let mut new_mailbox = self.mailbox.clone();
271 let msg = new_mailbox.pop_front().expect("checked non-empty");
272
273 (
274 ActorRuntime {
275 pending: self.pending.clone(),
276 mailbox: new_mailbox,
277 capacity: self.capacity,
278 blocked_on: self.blocked_on,
279 pending_send: self.pending_send.clone(),
280 },
281 Some(msg),
282 )
283 }
284
285 pub fn consume_mut(&mut self) -> Option<Message> {
287 self.mailbox.pop_front()
288 }
289
290 pub fn set_blocked(&self, on: ActorId) -> Self {
294 ActorRuntime {
295 pending: self.pending.clone(),
296 mailbox: self.mailbox.clone(),
297 capacity: self.capacity,
298 blocked_on: Some(on),
299 pending_send: self.pending_send.clone(),
300 }
301 }
302
303 pub fn set_blocked_mut(&mut self, on: ActorId) {
305 self.blocked_on = Some(on);
306 }
307
308 pub fn unblock(&self) -> Self {
312 ActorRuntime {
313 pending: self.pending.clone(),
314 mailbox: self.mailbox.clone(),
315 capacity: self.capacity,
316 blocked_on: None,
317 pending_send: self.pending_send.clone(),
318 }
319 }
320
321 pub fn unblock_mut(&mut self) {
323 self.blocked_on = None;
324 }
325
326 #[inline]
328 pub fn blocked_on(&self) -> Option<ActorId> {
329 self.blocked_on
330 }
331
332 #[inline]
334 pub fn is_blocked(&self) -> bool {
335 self.blocked_on.is_some()
336 }
337
338 #[inline]
340 pub fn capacity(&self) -> usize {
341 self.capacity
342 }
343
344 #[inline]
346 pub fn pending_len(&self) -> usize {
347 self.pending.len()
348 }
349
350 #[inline]
352 pub fn mailbox_len(&self) -> usize {
353 self.mailbox.len()
354 }
355
356 #[inline]
358 pub fn pending_send(&self) -> Option<&Message> {
359 self.pending_send.as_ref()
360 }
361
362 pub fn set_pending_send(&mut self, msg: Option<Message>) {
364 self.pending_send = msg;
365 }
366}
367
368impl Default for ActorRuntime {
369 fn default() -> Self {
370 ActorRuntime::empty(0)
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 fn make_test_message(id: MsgId) -> Message {
379 Message::new(id, 1, 2, SecurityLevel::Public, vec![1, 2, 3])
380 }
381
382 #[test]
383 fn test_actor_runtime_empty() {
384 let ar = ActorRuntime::empty(10);
385 assert_eq!(ar.capacity(), 10);
386 assert_eq!(ar.pending_len(), 0);
387 assert_eq!(ar.mailbox_len(), 0);
388 assert!(!ar.can_receive());
389 assert!(!ar.is_blocked());
390 }
391
392 #[test]
393 fn test_actor_runtime_enqueue_pending() {
394 let mut ar = ActorRuntime::empty(10);
395 let msg = make_test_message(1);
396
397 ar.enqueue_pending_mut(msg);
398 assert_eq!(ar.pending_len(), 1);
399 }
400
401 #[test]
402 fn test_actor_runtime_enqueue_pending_increases() {
403 let ar = ActorRuntime::empty(10);
405 let msg = make_test_message(1);
406
407 let ar2 = ar.enqueue_pending(msg);
408 assert_eq!(ar2.pending_len(), ar.pending_len() + 1);
409 }
410
411 #[test]
412 fn test_actor_runtime_enqueue_pending_preserves_mailbox() {
413 let ar = ActorRuntime::empty(10);
415 let msg = make_test_message(1);
416
417 let ar2 = ar.enqueue_pending(msg);
418 assert_eq!(ar2.mailbox_len(), ar.mailbox_len());
419 }
420
421 #[test]
422 fn test_actor_runtime_deliver() {
423 let mut ar = ActorRuntime::empty(10);
424 let msg = make_test_message(1);
425
426 ar.enqueue_pending_mut(msg);
427 assert_eq!(ar.pending_len(), 1);
428 assert_eq!(ar.mailbox_len(), 0);
429
430 let result = ar.deliver_mut();
431 assert!(matches!(result, Ok(true)));
432 assert_eq!(ar.pending_len(), 0);
433 assert_eq!(ar.mailbox_len(), 1);
434 }
435
436 #[test]
437 fn test_actor_runtime_deliver_decreases_pending() {
438 let ar = ActorRuntime::empty(10);
440 let msg = make_test_message(1);
441
442 let ar = ar.enqueue_pending(msg);
443 let ar2 = ar.deliver();
444
445 assert!(ar2.pending_len() < ar.pending_len());
446 }
447
448 #[test]
449 fn test_actor_runtime_deliver_increases_mailbox() {
450 let ar = ActorRuntime::empty(10);
452 let msg = make_test_message(1);
453
454 let ar = ar.enqueue_pending(msg);
455 let ar2 = ar.deliver();
456
457 assert_eq!(ar2.mailbox_len(), ar.mailbox_len() + 1);
458 }
459
460 #[test]
461 fn test_actor_runtime_consume() {
462 let mut ar = ActorRuntime::empty(10);
463 let msg = make_test_message(42);
464
465 ar.enqueue_pending_mut(msg);
466 ar.deliver_mut().expect("deliver should succeed");
467
468 let consumed = ar.consume_mut();
469 assert!(consumed.is_some());
470 assert_eq!(consumed.map(|m| m.id()), Some(42));
471 assert_eq!(ar.mailbox_len(), 0);
472 }
473
474 #[test]
475 fn test_actor_runtime_consume_decreases_mailbox() {
476 let ar = ActorRuntime::empty(10);
478 let msg = make_test_message(1);
479
480 let ar = ar.enqueue_pending(msg);
481 let ar = ar.deliver();
482 let (ar2, _) = ar.consume();
483
484 assert!(ar2.mailbox_len() < ar.mailbox_len());
485 }
486
487 #[test]
488 fn test_actor_runtime_consume_preserves_capacity() {
489 let ar = ActorRuntime::empty(10);
491 let msg = make_test_message(1);
492
493 let ar = ar.enqueue_pending(msg);
494 let ar = ar.deliver();
495 let (ar2, _) = ar.consume();
496
497 assert_eq!(ar2.capacity(), ar.capacity());
498 }
499
500 #[test]
501 fn test_actor_runtime_consume_preserves_blocked_on() {
502 let ar = ActorRuntime::empty(10);
504 let msg = make_test_message(1);
505
506 let ar = ar.enqueue_pending(msg);
507 let ar = ar.deliver();
508 let ar = ar.set_blocked(99);
509 let (ar2, _) = ar.consume();
510
511 assert_eq!(ar2.blocked_on(), ar.blocked_on());
512 }
513
514 #[test]
515 fn test_actor_runtime_set_blocked() {
516 let ar = ActorRuntime::empty(10);
518 let ar2 = ar.set_blocked(42);
519
520 assert_eq!(ar2.blocked_on(), Some(42));
521 }
522
523 #[test]
524 fn test_actor_runtime_set_blocked_preserves_mailbox() {
525 let ar = ActorRuntime::empty(10);
527 let ar2 = ar.set_blocked(42);
528
529 assert_eq!(ar2.mailbox_len(), ar.mailbox_len());
530 }
531
532 #[test]
533 fn test_actor_runtime_unblock_clears() {
534 let ar = ActorRuntime::empty(10);
536 let ar = ar.set_blocked(42);
537 let ar2 = ar.unblock();
538
539 assert_eq!(ar2.blocked_on(), None);
540 }
541
542 #[test]
543 fn test_actor_runtime_unblock_preserves_mailbox() {
544 let ar = ActorRuntime::empty(10);
546 let ar = ar.set_blocked(42);
547 let ar2 = ar.unblock();
548
549 assert_eq!(ar2.mailbox_len(), ar.mailbox_len());
550 }
551
552 #[test]
553 fn test_actor_runtime_mailbox_full() {
554 let mut ar = ActorRuntime::empty(2);
555
556 ar.enqueue_pending_mut(make_test_message(1));
558 ar.deliver_mut().expect("deliver 1");
559 ar.enqueue_pending_mut(make_test_message(2));
560 ar.deliver_mut().expect("deliver 2");
561
562 assert!(!ar.mailbox_has_space());
564 assert_eq!(ar.mailbox_len(), 2);
565
566 ar.enqueue_pending_mut(make_test_message(3));
568 let result = ar.deliver_mut();
569 assert!(matches!(result, Ok(false))); }
571
572 #[test]
573 fn test_message_accessors() {
574 let msg = Message::new(42, 1, 2, SecurityLevel::Confidential, vec![10, 20, 30]);
575
576 assert_eq!(msg.id(), 42);
577 assert_eq!(msg.src(), 1);
578 assert_eq!(msg.dst(), 2);
579 assert_eq!(msg.level(), SecurityLevel::Confidential);
580 assert_eq!(msg.body(), &vec![10, 20, 30]);
581 }
582}