improve newtypes

This commit is contained in:
Nikita Vilunov 2023-02-14 20:07:07 +01:00
parent c845f5d4ca
commit 265b78dc51
3 changed files with 46 additions and 21 deletions

View File

@ -25,9 +25,21 @@ use crate::{
util::table::{AnonTable, Key as AnonKey},
};
/// Opaque player identifier.
/// Opaque player identifier. Cannot contain spaces, must be shorter than 32.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PlayerId(pub ByteVec);
pub struct PlayerId(ByteVec);
impl PlayerId {
pub fn from_bytes(bytes: ByteVec) -> Result<PlayerId> {
if bytes.len() > 32 {
return Err(anyhow::Error::msg("Nickname cannot be longer than 32 symbols"));
}
if bytes.contains(&b' ') {
return Err(anyhow::Error::msg("Nickname cannot contain spaces"));
}
Ok(PlayerId(bytes))
}
pub fn as_bytes(&self) -> &ByteVec { &self.0 }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ConnectionId(pub AnonKey);

View File

@ -17,7 +17,19 @@ use super::player::{ConnectionId, IncomingPlayerEvent};
/// Opaque room id
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RoomId(pub ByteVec);
pub struct RoomId(ByteVec);
impl RoomId {
pub fn from_bytes(bytes: ByteVec) -> Result<RoomId> {
if bytes.len() > 32 {
return Err(anyhow::Error::msg("Room name cannot be longer than 32 symbols"));
}
if bytes.contains(&b' ') {
return Err(anyhow::Error::msg("Room name cannot contain spaces"));
}
Ok(RoomId(bytes))
}
pub fn as_bytes(&self) -> &ByteVec { &self.0 }
}
/// Shared datastructure for storing metadata about rooms.
#[derive(Clone)]

View File

@ -152,7 +152,7 @@ async fn handle_registered_socket<'a>(
let mut buffer = vec![];
log::info!("Handling registered user: {user:?}");
let player_id = PlayerId(user.nickname.clone());
let player_id = PlayerId::from_bytes(user.nickname.clone())?;
let mut connection = players.connect_to_player(player_id.clone()).await;
ServerMessage {
@ -214,7 +214,7 @@ async fn handle_registered_socket<'a>(
produce_on_join_cmd_messages(
&config,
&user,
&Chan::Global(room.id.0.clone()),
&Chan::Global(room.id.as_bytes().clone()),
room,
writer,
)
@ -243,7 +243,7 @@ async fn handle_registered_socket<'a>(
if player_id == author_id {
if let Some(room) = rooms.get_room(&room_id) {
let room_info = room.get_room_info().await;
let chan = Chan::Global(room_id.0);
let chan = Chan::Global(room_id.as_bytes().clone());
produce_on_join_cmd_messages(&config, &user, &chan, &room_info, writer).await?;
writer.flush().await?;
} else {
@ -252,8 +252,8 @@ async fn handle_registered_socket<'a>(
} else {
ServerMessage {
tags: vec![],
sender: Some(author_id.0.clone()),
body: ServerMessageBody::Join(Chan::Global(room_id.0)),
sender: Some(author_id.as_bytes().clone()),
body: ServerMessageBody::Join(Chan::Global(room_id.as_bytes().clone())),
}.write_async(writer).await?;
writer.flush().await?
}
@ -262,8 +262,8 @@ async fn handle_registered_socket<'a>(
if player_id != author_id || connection.connection_id != connection_id {
ServerMessage {
tags: vec![],
sender: Some(author_id.0.clone()),
body: ServerMessageBody::PrivateMessage { target: Recipient::Chan(Chan::Global(room_id.0)), body: body.as_bytes().to_vec() }
sender: Some(author_id.as_bytes().clone()),
body: ServerMessageBody::PrivateMessage { target: Recipient::Chan(Chan::Global(room_id.as_bytes().clone())), body: body.as_bytes().to_vec() }
}.write_async(writer).await?;
writer.flush().await?
}
@ -274,7 +274,7 @@ async fn handle_registered_socket<'a>(
sender: Some(config.server_name.as_bytes().to_vec()),
body: ServerMessageBody::N332Topic {
client: user.nickname.clone(),
chat: Chan::Global(room_id.0.clone()),
chat: Chan::Global(room_id.as_bytes().clone()),
topic: new_topic,
},
}.write_async(writer).await?;
@ -315,11 +315,10 @@ async fn handle_incoming_message(
handle_join(&config, &user, user_handle, chan, writer).await?;
}
ClientMessage::PrivateMessage { recipient, body } => match recipient {
Recipient::Chan(Chan::Global(room)) => match String::from_utf8(body) {
Recipient::Chan(Chan::Global(chan)) => match String::from_utf8(body) {
Ok(body) => {
user_handle
.send_message(RoomId(room.clone()), body.clone())
.await
let room_id = RoomId::from_bytes(chan)?;
user_handle.send_message(room_id, body.clone()).await
}
Err(err) => log::warn!("failed to parse incoming message: {err}"),
},
@ -327,8 +326,9 @@ async fn handle_incoming_message(
},
ClientMessage::Topic { chan, topic } => {
match chan {
Chan::Global(ref room) => {
let room = rooms.get_room(&RoomId(room.clone()));
Chan::Global(chan) => {
let room_id = RoomId::from_bytes(chan)?;
let room = rooms.get_room(&room_id);
if let Some(mut room) = room {
room.set_topic(topic).await;
}
@ -353,8 +353,9 @@ async fn handle_join(
writer: &mut (impl AsyncWrite + Unpin),
) -> Result<()> {
match chan {
Chan::Global(ref room) => {
let room_info = user_handle.join_room(RoomId(room.clone())).await?;
Chan::Global(chan) => {
let room_id = RoomId::from_bytes(chan.clone())?;
let room_info = user_handle.join_room(room_id).await?;
}
Chan::Local(_) => {}
};
@ -387,13 +388,13 @@ async fn produce_on_join_cmd_messages(
.write_async(writer)
.await?;
let mut members = if let Some(head) = room_info.members.first() {
head.0.clone()
head.as_bytes().clone()
} else {
user.nickname.clone()
};
for i in &room_info.members[1..] {
members.push(b' ');
members.extend(&i.0);
members.extend(i.as_bytes());
}
ServerMessage {
tags: vec![],