Rollback to Chan

This commit is contained in:
Mikhail 2024-05-30 20:05:28 +02:00
parent 7efbea7b71
commit a3e41ad11d
4 changed files with 48 additions and 55 deletions

View File

@ -25,7 +25,7 @@ use proto_irc::client::{client_message, ClientMessage};
use proto_irc::server::CapSubBody; use proto_irc::server::CapSubBody;
use proto_irc::server::{AwayStatus, ServerMessage, ServerMessageBody}; use proto_irc::server::{AwayStatus, ServerMessage, ServerMessageBody};
use proto_irc::user::PrefixedNick; use proto_irc::user::PrefixedNick;
use proto_irc::{ChannelName, Recipient, Tag}; use proto_irc::{Chan, Recipient, Tag};
use sasl::AuthBody; use sasl::AuthBody;
mod cap; mod cap;
use handler::Handler; use handler::Handler;
@ -491,14 +491,7 @@ async fn handle_registered_socket<'a>(
let rooms_list = connection.get_rooms().await?; let rooms_list = connection.get_rooms().await?;
for room in &rooms_list { for room in &rooms_list {
produce_on_join_cmd_messages( produce_on_join_cmd_messages(&config, &user, &Chan::Global(room.id.as_inner().clone()), room, writer).await?;
&config,
&user,
&ChannelName::Global(room.id.as_inner().clone()),
room,
writer,
)
.await?;
} }
writer.flush().await?; writer.flush().await?;
@ -583,7 +576,7 @@ async fn handle_update(
if player_id == &new_member_id { if player_id == &new_member_id {
if let Some(room) = core.get_room(&room_id).await { if let Some(room) = core.get_room(&room_id).await {
let room_info = room.get_room_info().await; let room_info = room.get_room_info().await;
let chan = ChannelName::Global(room_id.as_inner().clone()); let chan = Chan::Global(room_id.as_inner().clone());
produce_on_join_cmd_messages(&config, &user, &chan, &room_info, writer).await?; produce_on_join_cmd_messages(&config, &user, &chan, &room_info, writer).await?;
writer.flush().await?; writer.flush().await?;
} else { } else {
@ -593,7 +586,7 @@ async fn handle_update(
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(new_member_id.as_inner().clone()), sender: Some(new_member_id.as_inner().clone()),
body: ServerMessageBody::Join(ChannelName::Global(room_id.as_inner().clone())), body: ServerMessageBody::Join(Chan::Global(room_id.as_inner().clone())),
} }
.write_async(writer) .write_async(writer)
.await?; .await?;
@ -607,7 +600,7 @@ async fn handle_update(
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(former_member_id.as_inner().clone()), sender: Some(former_member_id.as_inner().clone()),
body: ServerMessageBody::Part(ChannelName::Global(room_id.as_inner().clone())), body: ServerMessageBody::Part(Chan::Global(room_id.as_inner().clone())),
} }
.write_async(writer) .write_async(writer)
.await?; .await?;
@ -631,7 +624,7 @@ async fn handle_update(
tags, tags,
sender: Some(author_id.as_inner().clone()), sender: Some(author_id.as_inner().clone()),
body: ServerMessageBody::PrivateMessage { body: ServerMessageBody::PrivateMessage {
target: Recipient::Chan(ChannelName::Global(room_id.as_inner().clone())), target: Recipient::Chan(Chan::Global(room_id.as_inner().clone())),
body: body.clone(), body: body.clone(),
}, },
} }
@ -645,7 +638,7 @@ async fn handle_update(
sender: Some(config.server_name.clone()), sender: Some(config.server_name.clone()),
body: ServerMessageBody::N332Topic { body: ServerMessageBody::N332Topic {
client: user.nickname.clone(), client: user.nickname.clone(),
chat: ChannelName::Global(room_id.as_inner().clone()), chat: Chan::Global(room_id.as_inner().clone()),
topic: new_topic, topic: new_topic,
}, },
} }
@ -658,7 +651,7 @@ async fn handle_update(
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(player_id.as_inner().clone()), sender: Some(player_id.as_inner().clone()),
body: ServerMessageBody::Part(ChannelName::Global(room_id.as_inner().clone())), body: ServerMessageBody::Part(Chan::Global(room_id.as_inner().clone())),
} }
.write_async(writer) .write_async(writer)
.await?; .await?;
@ -733,7 +726,7 @@ async fn handle_incoming_message(
handle_part(config, user, user_handle, &chan, writer).await?; handle_part(config, user, user_handle, &chan, writer).await?;
} }
ClientMessage::PrivateMessage { recipient, body } => match recipient { ClientMessage::PrivateMessage { recipient, body } => match recipient {
Recipient::Chan(ChannelName::Global(chan)) => { Recipient::Chan(Chan::Global(chan)) => {
let room_id = RoomId::try_from(chan)?; let room_id = RoomId::try_from(chan)?;
user_handle.send_message(room_id, body).await?; user_handle.send_message(room_id, body).await?;
} }
@ -745,7 +738,7 @@ async fn handle_incoming_message(
}, },
ClientMessage::Topic { chan, topic } => { ClientMessage::Topic { chan, topic } => {
match chan { match chan {
ChannelName::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?; user_handle.change_topic(room_id.clone(), topic.clone()).await?;
ServerMessage { ServerMessage {
@ -753,7 +746,7 @@ async fn handle_incoming_message(
sender: Some(config.server_name.clone()), sender: Some(config.server_name.clone()),
body: ServerMessageBody::N332Topic { body: ServerMessageBody::N332Topic {
client: user.nickname.clone(), client: user.nickname.clone(),
chat: ChannelName::Global(room_id.as_inner().clone()), chat: Chan::Global(room_id.as_inner().clone()),
topic, topic,
}, },
} }
@ -761,7 +754,7 @@ async fn handle_incoming_message(
.await?; .await?;
writer.flush().await?; writer.flush().await?;
} }
ChannelName::Local(_) => {} Chan::Local(_) => {}
}; };
} }
ClientMessage::Who { target } => match &target { ClientMessage::Who { target } => match &target {
@ -787,7 +780,7 @@ async fn handle_incoming_message(
.await?; .await?;
writer.flush().await?; writer.flush().await?;
} }
Recipient::Chan(ChannelName::Global(chan)) => { Recipient::Chan(Chan::Global(chan)) => {
let room = core.get_room(&RoomId::try_from(chan.clone())?).await; let room = core.get_room(&RoomId::try_from(chan.clone())?).await;
if let Some(room) = room { if let Some(room) = room {
let room_info = room.get_room_info().await; let room_info = room.get_room_info().await;
@ -814,7 +807,7 @@ async fn handle_incoming_message(
.await?; .await?;
writer.flush().await?; writer.flush().await?;
} }
Recipient::Chan(ChannelName::Local(_)) => { Recipient::Chan(Chan::Local(_)) => {
log::warn!("Local chans not supported"); log::warn!("Local chans not supported");
} }
}, },
@ -869,8 +862,8 @@ async fn handle_incoming_message(
} }
ClientMessage::ChatHistory { chan, limit } => { ClientMessage::ChatHistory { chan, limit } => {
let channel_name = match chan.clone() { let channel_name = match chan.clone() {
ChannelName::Global(chan) => chan, Chan::Global(chan) => chan,
ChannelName::Local(chan) => chan, Chan::Local(chan) => chan,
}; };
let room = core.get_room(&RoomId::try_from(channel_name.clone())?).await; let room = core.get_room(&RoomId::try_from(channel_name.clone())?).await;
if let Some(room) = room { if let Some(room) = room {
@ -934,11 +927,11 @@ async fn handle_join(
config: &ServerConfig, config: &ServerConfig,
user: &RegisteredUser, user: &RegisteredUser,
user_handle: &mut PlayerConnection, user_handle: &mut PlayerConnection,
chan: &ChannelName, chan: &Chan,
writer: &mut (impl AsyncWrite + Unpin), writer: &mut (impl AsyncWrite + Unpin),
) -> Result<()> { ) -> Result<()> {
match chan { match chan {
ChannelName::Global(chan_name) => { Chan::Global(chan_name) => {
let room_id = RoomId::try_from(chan_name.clone())?; let room_id = RoomId::try_from(chan_name.clone())?;
match user_handle.join_room(room_id).await? { match user_handle.join_room(room_id).await? {
JoinResult::Success(room_info) => { JoinResult::Success(room_info) => {
@ -963,7 +956,7 @@ async fn handle_join(
} }
writer.flush().await?; writer.flush().await?;
} }
ChannelName::Local(_) => { Chan::Local(_) => {
// TODO handle join attempts to local chans with an error, we don't support these // TODO handle join attempts to local chans with an error, we don't support these
} }
}; };
@ -974,16 +967,16 @@ async fn handle_part(
config: &ServerConfig, config: &ServerConfig,
user: &RegisteredUser, user: &RegisteredUser,
user_handle: &mut PlayerConnection, user_handle: &mut PlayerConnection,
chan: &ChannelName, chan: &Chan,
writer: &mut (impl AsyncWrite + Unpin), writer: &mut (impl AsyncWrite + Unpin),
) -> Result<()> { ) -> Result<()> {
if let ChannelName::Global(chan_name) = chan { if let Chan::Global(chan_name) = chan {
let room_id = RoomId::try_from(chan_name.clone())?; let room_id = RoomId::try_from(chan_name.clone())?;
user_handle.leave_room(room_id).await?; user_handle.leave_room(room_id).await?;
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(user.nickname.clone()), sender: Some(user.nickname.clone()),
body: ServerMessageBody::Part(ChannelName::Global(chan_name.clone())), body: ServerMessageBody::Part(Chan::Global(chan_name.clone())),
} }
.write_async(writer) .write_async(writer)
.await?; .await?;
@ -997,7 +990,7 @@ async fn handle_part(
async fn produce_on_join_cmd_messages( async fn produce_on_join_cmd_messages(
config: &ServerConfig, config: &ServerConfig,
user: &RegisteredUser, user: &RegisteredUser,
chan: &ChannelName, chan: &Chan,
room_info: &RoomInfo, room_info: &RoomInfo,
writer: &mut (impl AsyncWrite + Unpin), writer: &mut (impl AsyncWrite + Unpin),
) -> Result<()> { ) -> Result<()> {

View File

@ -33,7 +33,7 @@ pub enum ClientMessage {
realname: Str, realname: Str,
}, },
/// `JOIN <chan>` /// `JOIN <chan>`
Join(ChannelName), Join(Chan),
/// `MODE <target>` /// `MODE <target>`
Mode { Mode {
target: Recipient, target: Recipient,
@ -48,11 +48,11 @@ pub enum ClientMessage {
}, },
/// `TOPIC <chan> :<topic>` /// `TOPIC <chan> :<topic>`
Topic { Topic {
chan: ChannelName, chan: Chan,
topic: Str, topic: Str,
}, },
Part { Part {
chan: ChannelName, chan: Chan,
message: Option<Str>, message: Option<Str>,
}, },
/// `PRIVMSG <target> :<msg>` /// `PRIVMSG <target> :<msg>`
@ -66,7 +66,7 @@ pub enum ClientMessage {
}, },
Authenticate(Str), Authenticate(Str),
ChatHistory { ChatHistory {
chan: ChannelName, chan: Chan,
limit: u32, limit: u32,
}, },
} }
@ -504,7 +504,7 @@ mod test {
fn test_client_message_part() { fn test_client_message_part() {
let input = "PART #chan :Pokasiki !!!"; let input = "PART #chan :Pokasiki !!!";
let expected = ClientMessage::Part { let expected = ClientMessage::Part {
chan: ChannelName::Global("chan".into()), chan: Chan::Global("chan".into()),
message: Some("Pokasiki !!!".into()), message: Some("Pokasiki !!!".into()),
}; };
@ -516,7 +516,7 @@ mod test {
fn test_client_message_part_empty() { fn test_client_message_part_empty() {
let input = "PART #chan"; let input = "PART #chan";
let expected = ClientMessage::Part { let expected = ClientMessage::Part {
chan: ChannelName::Global("chan".into()), chan: Chan::Global("chan".into()),
message: None, message: None,
}; };
@ -548,7 +548,7 @@ mod test {
fn test_client_chat_history_latest() { fn test_client_chat_history_latest() {
let input = "CHATHISTORY LATEST #chan * 10"; let input = "CHATHISTORY LATEST #chan * 10";
let expected = ClientMessage::ChatHistory { let expected = ClientMessage::ChatHistory {
chan: ChannelName::Global("chan".into()), chan: Chan::Global("chan".into()),
limit: 10, limit: 10,
}; };

View File

@ -48,20 +48,20 @@ fn params(input: &str) -> IResult<&str, &str> {
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum ChannelName { pub enum Chan {
/// `#<name>` — network-global channel, available from any server in the network. /// `#<name>` — network-global channel, available from any server in the network.
Global(Str), Global(Str),
/// `&<name>` — server-local channel, available only to connections to the same server. Rarely used in practice. /// `&<name>` — server-local channel, available only to connections to the same server. Rarely used in practice.
Local(Str), Local(Str),
} }
impl ChannelName { impl Chan {
pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> { pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> {
match self { match self {
ChannelName::Global(name) => { Chan::Global(name) => {
writer.write_all(b"#").await?; writer.write_all(b"#").await?;
writer.write_all(name.as_bytes()).await?; writer.write_all(name.as_bytes()).await?;
} }
ChannelName::Local(name) => { Chan::Local(name) => {
writer.write_all(b"&").await?; writer.write_all(b"&").await?;
writer.write_all(name.as_bytes()).await?; writer.write_all(name.as_bytes()).await?;
} }
@ -70,17 +70,17 @@ impl ChannelName {
} }
} }
fn chan(input: &str) -> IResult<&str, ChannelName> { fn chan(input: &str) -> IResult<&str, Chan> {
fn chan_global(input: &str) -> IResult<&str, ChannelName> { fn chan_global(input: &str) -> IResult<&str, Chan> {
let (input, _) = tag("#")(input)?; let (input, _) = tag("#")(input)?;
let (input, name) = receiver(input)?; let (input, name) = receiver(input)?;
Ok((input, ChannelName::Global(name.into()))) Ok((input, Chan::Global(name.into())))
} }
fn chan_local(input: &str) -> IResult<&str, ChannelName> { fn chan_local(input: &str) -> IResult<&str, Chan> {
let (input, _) = tag("&")(input)?; let (input, _) = tag("&")(input)?;
let (input, name) = receiver(input)?; let (input, name) = receiver(input)?;
Ok((input, ChannelName::Local(name.into()))) Ok((input, Chan::Local(name.into())))
} }
alt((chan_global, chan_local))(input) alt((chan_global, chan_local))(input)
@ -89,7 +89,7 @@ fn chan(input: &str) -> IResult<&str, ChannelName> {
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum Recipient { pub enum Recipient {
Nick(Str), Nick(Str),
Chan(ChannelName), Chan(Chan),
} }
impl Recipient { impl Recipient {
pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> { pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> {
@ -125,7 +125,7 @@ mod test {
#[test] #[test]
fn test_chan_global() { fn test_chan_global() {
let input = "#testchan"; let input = "#testchan";
let expected = ChannelName::Global("testchan".into()); let expected = Chan::Global("testchan".into());
let result = chan(input); let result = chan(input);
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result)); assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
@ -139,7 +139,7 @@ mod test {
#[test] #[test]
fn test_chan_local() { fn test_chan_local() {
let input = "&localchan"; let input = "&localchan";
let expected = ChannelName::Local("localchan".into()); let expected = Chan::Local("localchan".into());
let result = chan(input); let result = chan(input);
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result)); assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));

View File

@ -69,8 +69,8 @@ pub enum ServerMessageBody {
target: Recipient, target: Recipient,
body: Str, body: Str,
}, },
Join(ChannelName), Join(Chan),
Part(ChannelName), Part(Chan),
Error { Error {
reason: Str, reason: Str,
}, },
@ -121,7 +121,7 @@ pub enum ServerMessageBody {
}, },
N332Topic { N332Topic {
client: Str, client: Str,
chat: ChannelName, chat: Chan,
topic: Str, topic: Str,
}, },
/// A reply to a client's [Who](crate::protos::irc::client::ClientMessage::Who) request. /// A reply to a client's [Who](crate::protos::irc::client::ClientMessage::Who) request.
@ -141,12 +141,12 @@ pub enum ServerMessageBody {
}, },
N353NamesReply { N353NamesReply {
client: Str, client: Str,
chan: ChannelName, chan: Chan,
members: NonEmpty<PrefixedNick>, members: NonEmpty<PrefixedNick>,
}, },
N366NamesReplyEnd { N366NamesReplyEnd {
client: Str, client: Str,
chan: ChannelName, chan: Chan,
}, },
N431ErrNoNicknameGiven { N431ErrNoNicknameGiven {
client: Str, client: Str,
@ -154,7 +154,7 @@ pub enum ServerMessageBody {
}, },
N474BannedFromChan { N474BannedFromChan {
client: Str, client: Str,
chan: ChannelName, chan: Chan,
message: Str, message: Str,
}, },
N502UsersDontMatch { N502UsersDontMatch {