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

View File

@ -750,18 +750,23 @@ async fn handle_incoming_message(
match chan {
Chan::Global(chan) => {
let room_id = RoomId::try_from(chan)?;
user_handle.change_topic(room_id.clone(), topic.clone()).await?;
ServerMessage {
tags: vec![],
sender: Some(config.server_name.clone()),
body: ServerMessageBody::N332Topic {
client: user.nickname.clone(),
chat: Chan::Global(room_id.as_inner().clone()),
topic,
},
let res = user_handle.change_topic(room_id.clone(), topic.clone()).await?;
match res {
ChangeRoomTopicResult::Success => {
ServerMessage {
tags: vec![],
sender: Some(config.server_name.clone()),
body: ServerMessageBody::N332Topic {
client: user.nickname.clone(),
chat: Chan::Global(room_id.as_inner().clone()),
topic,
},
}
.write_async(writer)
.await?;
}
ChangeRoomTopicResult::NoSuchRoom => {}
}
.write_async(writer)
.await?;
writer.flush().await?;
}
Chan::Local(_) => {}

View File

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