use crate::term::Term;
pub trait SelectFacility: Send + Sync {
fn message_count(&self) -> usize;
fn peek_message(&self, index: usize) -> Option<Term>;
fn remove_message(&self, index: usize);
}
pub struct MailboxSnapshot {
messages: Vec<Term>,
removed_index: std::sync::Mutex<Option<usize>>,
}
impl MailboxSnapshot {
#[must_use]
pub fn new(messages: Vec<Term>) -> Self {
Self {
messages,
removed_index: std::sync::Mutex::new(None),
}
}
#[must_use]
pub fn removed_index(&self) -> Option<usize> {
*self.removed_index.lock().unwrap_or_else(|e| e.into_inner())
}
}
impl SelectFacility for MailboxSnapshot {
fn message_count(&self) -> usize {
self.messages.len()
}
fn peek_message(&self, index: usize) -> Option<Term> {
self.messages.get(index).copied()
}
fn remove_message(&self, index: usize) {
*self.removed_index.lock().unwrap_or_else(|e| e.into_inner()) = Some(index);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::atom::Atom;
use crate::term::Term;
#[test]
fn snapshot_provides_message_count_and_peek() {
let messages = vec![Term::small_int(1), Term::small_int(2), Term::small_int(3)];
let snapshot = MailboxSnapshot::new(messages);
assert_eq!(snapshot.message_count(), 3);
assert_eq!(snapshot.peek_message(0), Some(Term::small_int(1)));
assert_eq!(snapshot.peek_message(1), Some(Term::small_int(2)));
assert_eq!(snapshot.peek_message(2), Some(Term::small_int(3)));
assert_eq!(snapshot.peek_message(3), None);
}
#[test]
fn snapshot_records_removed_index() {
let messages = vec![Term::atom(Atom::OK), Term::atom(Atom::ERROR)];
let snapshot = MailboxSnapshot::new(messages);
assert_eq!(snapshot.removed_index(), None);
snapshot.remove_message(1);
assert_eq!(snapshot.removed_index(), Some(1));
}
#[test]
fn empty_snapshot() {
let snapshot = MailboxSnapshot::new(Vec::new());
assert_eq!(snapshot.message_count(), 0);
assert_eq!(snapshot.peek_message(0), None);
assert_eq!(snapshot.removed_index(), None);
}
}