core: ADT for results of room joins

This commit is contained in:
Nikita Vilunov 2024-06-05 00:10:36 +02:00
parent 4e8eb09184
commit 2c828b482e
3 changed files with 41 additions and 24 deletions

View File

@ -78,9 +78,9 @@ impl PlayerConnection {
/// Handled in [Player::change_room_topic]. /// Handled in [Player::change_room_topic].
#[tracing::instrument(skip(self, new_topic), name = "PlayerConnection::change_topic")] #[tracing::instrument(skip(self, new_topic), name = "PlayerConnection::change_topic")]
pub async fn change_topic(&mut self, room_id: RoomId, new_topic: Str) -> Result<()> { pub async fn change_topic(&mut self, room_id: RoomId, new_topic: Str) -> Result<ChangeRoomTopicResult> {
let (promise, deferred) = oneshot(); let (promise, deferred) = oneshot();
let cmd = ClientCommand::ChangeTopic { let cmd = ClientCommand::ChangeRoomTopic {
room_id, room_id,
new_topic, new_topic,
promise, promise,
@ -207,10 +207,10 @@ pub enum ClientCommand {
body: Str, body: Str,
promise: Promise<Result<SendMessageResult>>, promise: Promise<Result<SendMessageResult>>,
}, },
ChangeTopic { ChangeRoomTopic {
room_id: RoomId, room_id: RoomId,
new_topic: Str, new_topic: Str,
promise: Promise<Result<()>>, promise: Promise<Result<ChangeRoomTopicResult>>,
}, },
GetRooms { GetRooms {
promise: Promise<Result<Vec<RoomInfo>>>, promise: Promise<Result<Vec<RoomInfo>>>,
@ -242,6 +242,11 @@ pub enum JoinResult {
Banned, Banned,
} }
pub enum ChangeRoomTopicResult {
Success,
NoSuchRoom,
}
pub enum SendMessageResult { pub enum SendMessageResult {
Success(DateTime<Utc>), Success(DateTime<Utc>),
NoSuchRoom, NoSuchRoom,
@ -510,7 +515,7 @@ impl Player {
let result = self.send_room_message(connection_id, room_id, body).await; let result = self.send_room_message(connection_id, room_id, body).await;
let _ = promise.send(result); let _ = promise.send(result);
} }
ClientCommand::ChangeTopic { ClientCommand::ChangeRoomTopic {
room_id, room_id,
new_topic, new_topic,
promise, promise,
@ -680,11 +685,15 @@ impl Player {
} }
#[tracing::instrument(skip(self, new_topic), name = "Player::change_room_topic")] #[tracing::instrument(skip(self, new_topic), name = "Player::change_room_topic")]
async fn change_room_topic(&mut self, connection_id: ConnectionId, room_id: RoomId, new_topic: Str) -> Result<()> { async fn change_room_topic(
&mut self,
connection_id: ConnectionId,
room_id: RoomId,
new_topic: Str,
) -> Result<ChangeRoomTopicResult> {
let Some(room) = self.my_rooms.get(&room_id) else { let Some(room) = self.my_rooms.get(&room_id) else {
tracing::info!("Room with ID {room_id:?} not found"); tracing::debug!("Room with ID {room_id:?} not found");
// TODO return Ok(ChangeRoomTopicResult::NoSuchRoom);
return Ok(());
}; };
match room { match room {
RoomRef::Local(room) => { RoomRef::Local(room) => {
@ -701,7 +710,7 @@ impl Player {
} }
let update = Updates::RoomTopicChanged { room_id, new_topic }; let update = Updates::RoomTopicChanged { room_id, new_topic };
self.broadcast_update(update, connection_id).await; self.broadcast_update(update, connection_id).await;
Ok(()) Ok(ChangeRoomTopicResult::Success)
} }
#[tracing::instrument(skip(self), name = "Player::get_rooms")] #[tracing::instrument(skip(self), name = "Player::get_rooms")]

View File

@ -750,7 +750,9 @@ async fn handle_incoming_message(
match chan { match chan {
Chan::Global(chan) => { Chan::Global(chan) => {
let room_id = RoomId::try_from(chan)?; let room_id = RoomId::try_from(chan)?;
user_handle.change_topic(room_id.clone(), topic.clone()).await?; let res = user_handle.change_topic(room_id.clone(), topic.clone()).await?;
match res {
ChangeRoomTopicResult::Success => {
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(config.server_name.clone()), sender: Some(config.server_name.clone()),
@ -762,6 +764,9 @@ async fn handle_incoming_message(
} }
.write_async(writer) .write_async(writer)
.await?; .await?;
}
ChangeRoomTopicResult::NoSuchRoom => {}
}
writer.flush().await?; writer.flush().await?;
} }
Chan::Local(_) => {} Chan::Local(_) => {}

View File

@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize};
use tokio::net::TcpListener; use tokio::net::TcpListener;
use lavina_core::auth::UpdatePasswordResult; use lavina_core::auth::UpdatePasswordResult;
use lavina_core::player::{PlayerConnectionResult, PlayerId, SendMessageResult}; use lavina_core::player::{ChangeRoomTopicResult, PlayerConnectionResult, PlayerId, SendMessageResult};
use lavina_core::prelude::*; use lavina_core::prelude::*;
use lavina_core::room::RoomId; use lavina_core::room::RoomId;
use lavina_core::terminator::Terminator; use lavina_core::terminator::Terminator;
@ -204,8 +204,11 @@ async fn endpoint_set_room_topic(
return Ok(player_not_found()); return Ok(player_not_found());
} }
}; };
connection.change_topic(room_id, req.topic.into()).await?; let res = connection.change_topic(room_id, req.topic.into()).await?;
Ok(empty_204_request()) match res {
ChangeRoomTopicResult::Success => Ok(empty_204_request()),
ChangeRoomTopicResult::NoSuchRoom => Ok(room_not_found()),
}
} }
fn endpoint_not_found() -> Response<Full<Bytes>> { fn endpoint_not_found() -> Response<Full<Bytes>> {