#![cfg(feature = "macros")]
use std::collections::HashSet;
use actix::prelude::*;
struct SessionActor {
sessions: HashSet<usize>,
}
impl SessionActor {
fn new() -> Self {
Self {
sessions: HashSet::new(),
}
}
fn session_count(&self) -> usize {
self.sessions.len()
}
fn sessions(&self) -> Vec<usize> {
self.sessions.iter().cloned().collect()
}
fn add_session(&mut self, id: usize) -> Result<usize, String> {
match self.sessions.insert(id) {
false => Err(String::from("Duplicate session ID")),
true => Ok(id),
}
}
}
impl Actor for SessionActor {
type Context = Context<Self>;
}
#[derive(Message)]
#[rtype(result = "Result<usize, String>")]
struct AddSession(usize);
impl Handler<AddSession> for SessionActor {
type Result = Result<usize, String>;
fn handle(&mut self, id: AddSession, _: &mut Context<Self>) -> Self::Result {
self.add_session(id.0)
}
}
#[derive(Message)]
#[rtype(usize)]
struct GetSessionCount;
impl Handler<GetSessionCount> for SessionActor {
type Result = usize;
fn handle(&mut self, _: GetSessionCount, _: &mut Context<Self>) -> Self::Result {
self.session_count()
}
}
#[derive(Message)]
#[rtype(result = "Vec<usize>")]
struct GetConnectedSessions;
impl Handler<GetConnectedSessions> for SessionActor {
type Result = Vec<usize>;
fn handle(&mut self, _: GetConnectedSessions, _: &mut Context<Self>) -> Self::Result {
self.sessions()
}
}
#[derive(Message)]
#[rtype(result = "Option<usize>")]
struct GetSessionById(usize);
impl Handler<GetSessionById> for SessionActor {
type Result = Option<usize>;
fn handle(&mut self, id: GetSessionById, _: &mut Context<Self>) -> Self::Result {
self.sessions.get(&id.0).cloned()
}
}
#[actix::test]
async fn test_different_message_result_types() {
let actor = SessionActor::new().start();
let count = actor.send(GetSessionCount).await.unwrap();
assert!(
count == 0,
"Invalid message response as the ActorSession's sessions should be empty by default"
);
actor
.send(AddSession(1))
.await
.unwrap()
.expect("Duplicate session ID");
actor
.send(AddSession(2))
.await
.unwrap()
.expect("Duplicate session ID");
let count = actor.send(GetSessionCount).await.unwrap();
assert!(count == 2, "2 sessions should have been added");
let sessions: Vec<usize> = actor.send(GetConnectedSessions).await.unwrap();
assert!(
sessions.len() == 2,
"2 sessions should have been added AND returned from the `GetConnectedSessions` message"
);
let id = actor.send(GetSessionById(1)).await.unwrap();
assert!(id.is_some(), "Session with id `1` should have been added");
let invalid_id = actor.send(GetSessionById(50)).await.unwrap();
assert!(
invalid_id.is_none(),
"No session with id `50` should be present"
);
let duplicate_session = actor.send(AddSession(1)).await.unwrap();
assert!(
duplicate_session.is_err(),
"Session with id `1` should already have been inserted"
);
}