From 80dad0012560d723585d77ca7d9d6efdf93e2ae9 Mon Sep 17 00:00:00 2001 From: Joscha Date: Wed, 17 Aug 2022 23:04:43 +0200 Subject: [PATCH 001/383] Fix crash when connecting to some types of room --- CHANGELOG.md | 4 ++++ src/ui/rooms.rs | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfc25da..31ced02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ Procedure when bumping the version number: ## Unreleased +### Fixed +- Crash when connecting to nonexistent rooms +- Crash when connecting to rooms that require authentication + ## v0.2.1 - 2022-08-11 ### Added diff --git a/src/ui/rooms.rs b/src/ui/rooms.rs index b4a5298..125907f 100644 --- a/src/ui/rooms.rs +++ b/src/ui/rooms.rs @@ -67,12 +67,19 @@ impl Rooms { /// - failed connection attempts, or /// - rooms that were deleted from the db. async fn stabilize_rooms(&mut self) { - let rooms_set = self + let mut rooms_set = self .vault .euph_rooms() .await .into_iter() .collect::>(); + + // Prevent room that is currently being shown from being removed. This + // could otherwise happen when connecting to a room that doesn't exist. + if let State::ShowRoom(name) = &self.state { + rooms_set.insert(name.clone()); + } + self.euph_rooms .retain(|n, r| !r.stopped() || rooms_set.contains(n)); From 6dc7d2bd0b2ad207f3e462567be7b6bcfc9db49d Mon Sep 17 00:00:00 2001 From: Joscha Date: Wed, 17 Aug 2022 23:06:49 +0200 Subject: [PATCH 002/383] Placate clippy --- src/ui/widgets/list.rs | 8 +++--- src/vault/euph.rs | 62 ++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/ui/widgets/list.rs b/src/ui/widgets/list.rs index 0935332..ab175f0 100644 --- a/src/ui/widgets/list.rs +++ b/src/ui/widgets/list.rs @@ -256,15 +256,15 @@ enum Row { impl Row { fn id(&self) -> Option<&Id> { match self { - Row::Unselectable { .. } => None, - Row::Selectable { id, .. } => Some(id), + Self::Unselectable { .. } => None, + Self::Selectable { id, .. } => Some(id), } } fn size(&self, frame: &mut Frame, max_width: Option, max_height: Option) -> Size { match self { - Row::Unselectable { normal } => normal.size(frame, max_width, max_height), - Row::Selectable { + Self::Unselectable { normal } => normal.size(frame, max_width, max_height), + Self::Selectable { normal, selected, .. } => { let normal_size = normal.size(frame, max_width, max_height); diff --git a/src/vault/euph.rs b/src/vault/euph.rs index 531aa74..d546f2d 100644 --- a/src/vault/euph.rs +++ b/src/vault/euph.rs @@ -481,70 +481,60 @@ pub(super) enum EuphRequest { impl EuphRequest { pub(super) fn perform(self, conn: &mut Connection) { let result = match self { - EuphRequest::GetCookies { result } => Self::get_cookies(conn, result), - EuphRequest::SetCookies { cookies } => Self::set_cookies(conn, cookies), - EuphRequest::GetRooms { result } => Self::get_rooms(conn, result), - EuphRequest::Join { room, time } => Self::join(conn, room, time), - EuphRequest::Delete { room } => Self::delete(conn, room), - EuphRequest::AddMsg { + Self::GetCookies { result } => Self::get_cookies(conn, result), + Self::SetCookies { cookies } => Self::set_cookies(conn, cookies), + Self::GetRooms { result } => Self::get_rooms(conn, result), + Self::Join { room, time } => Self::join(conn, room, time), + Self::Delete { room } => Self::delete(conn, room), + Self::AddMsg { room, msg, prev_msg, own_user_id, } => Self::add_msg(conn, room, *msg, prev_msg, own_user_id), - EuphRequest::AddMsgs { + Self::AddMsgs { room, msgs, next_msg, own_user_id, } => Self::add_msgs(conn, room, msgs, next_msg, own_user_id), - EuphRequest::GetLastSpan { room, result } => Self::get_last_span(conn, room, result), - EuphRequest::GetPath { room, id, result } => Self::get_path(conn, room, id, result), - EuphRequest::GetTree { room, root, result } => Self::get_tree(conn, room, root, result), - EuphRequest::GetFirstTreeId { room, result } => { - Self::get_first_tree_id(conn, room, result) - } - EuphRequest::GetLastTreeId { room, result } => { - Self::get_last_tree_id(conn, room, result) - } - EuphRequest::GetPrevTreeId { room, root, result } => { + Self::GetLastSpan { room, result } => Self::get_last_span(conn, room, result), + Self::GetPath { room, id, result } => Self::get_path(conn, room, id, result), + Self::GetTree { room, root, result } => Self::get_tree(conn, room, root, result), + Self::GetFirstTreeId { room, result } => Self::get_first_tree_id(conn, room, result), + Self::GetLastTreeId { room, result } => Self::get_last_tree_id(conn, room, result), + Self::GetPrevTreeId { room, root, result } => { Self::get_prev_tree_id(conn, room, root, result) } - EuphRequest::GetNextTreeId { room, root, result } => { + Self::GetNextTreeId { room, root, result } => { Self::get_next_tree_id(conn, room, root, result) } - EuphRequest::GetOldestMsgId { room, result } => { - Self::get_oldest_msg_id(conn, room, result) - } - EuphRequest::GetNewestMsgId { room, result } => { - Self::get_newest_msg_id(conn, room, result) - } - EuphRequest::GetOlderMsgId { room, id, result } => { + Self::GetOldestMsgId { room, result } => Self::get_oldest_msg_id(conn, room, result), + Self::GetNewestMsgId { room, result } => Self::get_newest_msg_id(conn, room, result), + Self::GetOlderMsgId { room, id, result } => { Self::get_older_msg_id(conn, room, id, result) } - EuphRequest::GetNewerMsgId { room, id, result } => { + Self::GetNewerMsgId { room, id, result } => { Self::get_newer_msg_id(conn, room, id, result) } - EuphRequest::GetOldestUnseenMsgId { room, result } => { + Self::GetOldestUnseenMsgId { room, result } => { Self::get_oldest_unseen_msg_id(conn, room, result) } - EuphRequest::GetNewestUnseenMsgId { room, result } => { + Self::GetNewestUnseenMsgId { room, result } => { Self::get_newest_unseen_msg_id(conn, room, result) } - EuphRequest::GetOlderUnseenMsgId { room, id, result } => { + Self::GetOlderUnseenMsgId { room, id, result } => { Self::get_older_unseen_msg_id(conn, room, id, result) } - EuphRequest::GetNewerUnseenMsgId { room, id, result } => { + Self::GetNewerUnseenMsgId { room, id, result } => { Self::get_newer_unseen_msg_id(conn, room, id, result) } - EuphRequest::GetUnseenMsgsCount { room, result } => { + Self::GetUnseenMsgsCount { room, result } => { Self::get_unseen_msgs_count(conn, room, result) } - EuphRequest::SetSeen { room, id, seen } => Self::set_seen(conn, room, id, seen), - EuphRequest::SetOlderSeen { room, id, seen } => { - Self::set_older_seen(conn, room, id, seen) - } - EuphRequest::GetChunkAtOffset { + Self::SetSeen { room, id, seen } => Self::set_seen(conn, room, id, seen), + Self::SetOlderSeen { room, id, seen } => Self::set_older_seen(conn, room, id, seen), + Self::GetChunkAtOffset { room, amount, offset, From d07b1051a9f10aecf4560c7dd0739f7e3aa9e794 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 18 Aug 2022 17:42:43 +0200 Subject: [PATCH 003/383] Add euphoxide dependency --- Cargo.lock | 52 ++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 7 +++++++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65c261d..63bbd3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,6 +192,7 @@ dependencies = [ "crossterm", "directories", "edit", + "euphoxide", "futures", "log", "palette", @@ -299,6 +300,21 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +[[package]] +name = "euphoxide" +version = "0.1.0" +source = "git+https://github.com/Garmelon/euphoxide.git?rev=643da74bcc24dc2eeb8746b45fbb986d1d000f0a#643da74bcc24dc2eeb8746b45fbb986d1d000f0a" +dependencies = [ + "futures", + "rand", + "serde", + "serde_json", + "thiserror", + "time", + "tokio", + "tokio-tungstenite", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -347,9 +363,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" dependencies = [ "futures-channel", "futures-core", @@ -362,9 +378,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" dependencies = [ "futures-core", "futures-sink", @@ -372,15 +388,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" dependencies = [ "futures-core", "futures-task", @@ -389,15 +405,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" dependencies = [ "proc-macro2", "quote", @@ -406,21 +422,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" dependencies = [ "futures-channel", "futures-core", diff --git a/Cargo.toml b/Cargo.toml index 9a659cb..a1aeb0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,13 @@ features = ["macros", "formatting", "parsing", "serde"] version = "0.17.2" features = ["rustls-tls-native-roots"] +[dependencies.euphoxide] +git = "https://github.com/Garmelon/euphoxide.git" +rev = "643da74bcc24dc2eeb8746b45fbb986d1d000f0a" + +# [patch."https://github.com/Garmelon/euphoxide.git"] +# toss = { path = "../euphoxide/" } + [dependencies.toss] git = "https://github.com/Garmelon/toss.git" rev = "45ece466c235cce6e998bbd404f915cad3628c8c" From 36b717ff8cb17e025b7ca8aadadb36a638c3f7d1 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 18 Aug 2022 18:13:49 +0200 Subject: [PATCH 004/383] Use euphoxide instead of euph module --- src/euph.rs | 5 +- src/euph/api.rs | 13 - src/euph/api/events.rs | 170 ------------- src/euph/api/packet.rs | 192 --------------- src/euph/api/room_cmds.rs | 116 --------- src/euph/api/session_cmds.rs | 43 ---- src/euph/api/types.rs | 391 ----------------------------- src/euph/conn.rs | 466 ----------------------------------- src/euph/room.rs | 9 +- src/euph/small_message.rs | 2 +- src/euph/util.rs | 35 +-- src/export/text.rs | 2 +- src/main.rs | 1 - src/replies.rs | 68 ----- src/ui/euph/room.rs | 5 +- src/ui/rooms.rs | 4 +- src/vault/euph.rs | 117 +++++---- 17 files changed, 83 insertions(+), 1556 deletions(-) delete mode 100644 src/euph/api.rs delete mode 100644 src/euph/api/events.rs delete mode 100644 src/euph/api/packet.rs delete mode 100644 src/euph/api/room_cmds.rs delete mode 100644 src/euph/api/session_cmds.rs delete mode 100644 src/euph/api/types.rs delete mode 100644 src/euph/conn.rs delete mode 100644 src/replies.rs diff --git a/src/euph.rs b/src/euph.rs index 01e60a3..2f4f2f2 100644 --- a/src/euph.rs +++ b/src/euph.rs @@ -1,10 +1,7 @@ -pub mod api; -mod conn; mod room; mod small_message; mod util; -pub use conn::{Joined, Joining, Status}; pub use room::Room; pub use small_message::SmallMessage; -pub use util::{hue, nick_color, nick_style}; +pub use util::{nick_color, nick_style}; diff --git a/src/euph/api.rs b/src/euph/api.rs deleted file mode 100644 index 95f76c7..0000000 --- a/src/euph/api.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Models the euphoria API at . - -mod events; -pub mod packet; -mod room_cmds; -mod session_cmds; -mod types; - -pub use events::*; -pub use packet::Data; -pub use room_cmds::*; -pub use session_cmds::*; -pub use types::*; diff --git a/src/euph/api/events.rs b/src/euph/api/events.rs deleted file mode 100644 index 1d79b03..0000000 --- a/src/euph/api/events.rs +++ /dev/null @@ -1,170 +0,0 @@ -//! Asynchronous events. - -use serde::{Deserialize, Serialize}; - -use super::{AuthOption, Message, PersonalAccountView, SessionView, Snowflake, Time, UserId}; - -/// Indicates that access to a room is denied. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BounceEvent { - /// The reason why access was denied. - pub reason: Option, - /// Authentication options that may be used. - pub auth_options: Option>, - /// Internal use only. - pub agent_id: Option, - /// Internal use only. - pub ip: Option, -} - -/// Indicates that the session is being closed. The client will subsequently be -/// disconnected. -/// -/// If the disconnect reason is `authentication changed`, the client should -/// immediately reconnect. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DisconnectEvent { - /// The reason for disconnection. - pub reason: String, -} - -/// Sent by the server to the client when a session is started. -/// -/// It includes information about the client's authentication and associated -/// identity. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HelloEvent { - /// The id of the agent or account logged into this session. - pub id: UserId, - /// Details about the user's account, if the session is logged in. - pub account: Option, - /// Details about the session. - pub session: SessionView, - /// If true, then the account has an explicit access grant to the current - /// room. - pub account_has_access: Option, - /// Whether the account's email address has been verified. - pub account_email_verified: Option, - /// If true, the session is connected to a private room. - pub room_is_private: bool, - /// The version of the code being run and served by the server. - pub version: String, -} - -/// Indicates a session just joined the room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct JoinEvent(pub SessionView); - -/// Sent to all sessions of an agent when that agent is logged in (except for -/// the session that issued the login command). -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct LoginEvent { - pub account_id: Snowflake, -} - -/// Sent to all sessions of an agent when that agent is logged out (except for -/// the session that issued the logout command). -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct LogoutEvent; - -/// Indicates some server-side event that impacts the presence of sessions in a -/// room. -/// -/// If the network event type is `partition`, then this should be treated as a -/// [`PartEvent`] for all sessions connected to the same server id/era combo. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NetworkEvent { - /// The type of network event; for now, always `partition`. - pub r#type: String, - /// The id of the affected server. - pub server_id: String, - /// The era of the affected server. - pub server_era: String, -} - -/// Announces a nick change by another session in the room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NickEvent { - /// The id of the session this name applies to. - pub session_id: String, - /// The id of the agent or account logged into the session. - pub id: UserId, - /// The previous name associated with the session. - pub from: String, - /// The name associated with the session henceforth. - pub to: String, -} - -/// Indicates that a message in the room has been modified or deleted. -/// -/// If the client offers a user interface and the indicated message is currently -/// displayed, it should update its display accordingly. -/// -/// The event packet includes a snapshot of the message post-edit. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EditMessageEvent { - /// The id of the edit. - pub edit_id: Snowflake, - /// The snapshot of the message post-edit. - #[serde(flatten)] - pub message: Message, -} - -/// Indicates a session just disconnected from the room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PartEvent(pub SessionView); - -/// Represents a server-to-client ping. -/// -/// The client should send back a ping-reply with the same value for the time -/// field as soon as possible (or risk disconnection). -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PingEvent { - /// A unix timestamp according to the server's clock. - pub time: Time, - /// The expected time of the next ping event, according to the server's - /// clock. - pub next: Time, -} - -/// Informs the client that another user wants to chat with them privately. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PmInitiateEvent { - /// The id of the user inviting the client to chat privately. - pub from: UserId, - /// The nick of the inviting user. - pub from_nick: String, - /// The room where the invitation was sent from. - pub from_room: String, - /// The private chat can be accessed at `/room/pm:`. - pub pm_id: Snowflake, -} - -/// Indicates a message received by the room from another session. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SendEvent(pub Message); - -/// Indicates that a session has successfully joined a room. -/// -/// It also offers a snapshot of the room’s state and recent history. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SnapshotEvent { - /// The id of the agent or account logged into this session. - pub identity: UserId, - /// The globally unique id of this session. - pub session_id: String, - /// The server’s version identifier. - pub version: String, - /// The list of all other sessions joined to the room (excluding this - /// session). - pub listing: Vec, - /// The most recent messages posted to the room (currently up to 100). - pub log: Vec, - /// The acting nick of the session; if omitted, client set nick before - /// speaking. - pub nick: Option, - /// If given, this room is for private chat with the given nick. - pub pm_with_nick: Option, - /// If given, this room is for private chat with the given user. - pub pm_with_user_id: Option, -} diff --git a/src/euph/api/packet.rs b/src/euph/api/packet.rs deleted file mode 100644 index e69de56..0000000 --- a/src/euph/api/packet.rs +++ /dev/null @@ -1,192 +0,0 @@ -use serde::{Deserialize, Serialize}; -use serde_json::Value; - -use super::PacketType; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Packet { - pub id: Option, - pub r#type: PacketType, - pub data: Option, - #[serde(skip_serializing)] - pub error: Option, - #[serde(default, skip_serializing)] - pub throttled: bool, - #[serde(skip_serializing)] - pub throttled_reason: Option, -} - -pub trait Command { - type Reply; -} - -macro_rules! packets { - ( $( $name:ident, )*) => { - #[derive(Debug, Clone)] - #[non_exhaustive] - pub enum Data { - $( $name(super::$name), )* - Unimplemented, - } - - impl Data { - pub fn from_value(ptype: PacketType, value: Value) -> serde_json::Result { - Ok(match ptype { - $( PacketType::$name => Self::$name(serde_json::from_value(value)?), )* - _ => Self::Unimplemented, - }) - } - - pub fn into_value(self) -> serde_json::Result { - Ok(match self{ - $( Self::$name(p) => serde_json::to_value(p)?, )* - Self::Unimplemented => panic!("using unimplemented data"), - }) - } - - pub fn packet_type(&self) -> PacketType { - match self { - $( Self::$name(_) => PacketType::$name, )* - Self::Unimplemented => panic!("using unimplemented data"), - } - } - } - - $( - impl From for Data { - fn from(p: super::$name) -> Self { - Self::$name(p) - } - } - - impl TryFrom for super::$name{ - type Error = (); - - fn try_from(value: Data) -> Result { - match value { - Data::$name(p) => Ok(p), - _ => Err(()) - } - } - } - )* - }; -} - -macro_rules! commands { - ( $( $cmd:ident => $rpl:ident, )* ) => { - $( - impl Command for super::$cmd { - type Reply = super::$rpl; - } - )* - }; -} - -packets! { - BounceEvent, - DisconnectEvent, - HelloEvent, - JoinEvent, - LoginEvent, - LogoutEvent, - NetworkEvent, - NickEvent, - EditMessageEvent, - PartEvent, - PingEvent, - PmInitiateEvent, - SendEvent, - SnapshotEvent, - Auth, - AuthReply, - Ping, - PingReply, - GetMessage, - GetMessageReply, - Log, - LogReply, - Nick, - NickReply, - PmInitiate, - PmInitiateReply, - Send, - SendReply, - Who, - WhoReply, -} - -commands! { - Auth => AuthReply, - Ping => PingReply, - GetMessage => GetMessageReply, - Log => LogReply, - Nick => NickReply, - PmInitiate => PmInitiateReply, - Send => SendReply, - Who => WhoReply, -} - -#[derive(Debug, Clone)] -pub struct ParsedPacket { - pub id: Option, - pub r#type: PacketType, - pub content: Result, - pub throttled: Option, -} - -impl ParsedPacket { - pub fn from_packet(packet: Packet) -> serde_json::Result { - let id = packet.id; - let r#type = packet.r#type; - - let content = if let Some(error) = packet.error { - Err(error) - } else { - let data = packet.data.unwrap_or_default(); - Ok(Data::from_value(r#type, data)?) - }; - - let throttled = if packet.throttled { - let reason = packet - .throttled_reason - .unwrap_or_else(|| "no reason given".to_string()); - Some(reason) - } else { - None - }; - - Ok(Self { - id, - r#type, - content, - throttled, - }) - } - - pub fn into_packet(self) -> serde_json::Result { - let id = self.id; - let r#type = self.r#type; - let throttled = self.throttled.is_some(); - let throttled_reason = self.throttled; - - Ok(match self.content { - Ok(data) => Packet { - id, - r#type, - data: Some(data.into_value()?), - error: None, - throttled, - throttled_reason, - }, - Err(error) => Packet { - id, - r#type, - data: None, - error: Some(error), - throttled, - throttled_reason, - }, - }) - } -} diff --git a/src/euph/api/room_cmds.rs b/src/euph/api/room_cmds.rs deleted file mode 100644 index 02dddd4..0000000 --- a/src/euph/api/room_cmds.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! Chat room commands. - -use serde::{Deserialize, Serialize}; - -use super::{Message, SessionView, Snowflake, UserId}; - -/// Retrieve the full content of a single message in the room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetMessage { - /// The id of the message to retrieve. - pub id: Snowflake, -} - -/// The message retrieved by [`GetMessage`]. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetMessageReply(pub Message); - -/// Request messages from the room's message log. -/// -/// This can be used to supplement the log provided by snapshot-event (for -/// example, when scrolling back further in history). -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Log { - /// Maximum number of messages to return (up to 1000). - pub n: usize, - /// Return messages prior to this snowflake. - pub before: Option, -} - -/// List of messages from the room's message log. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct LogReply { - /// List of messages returned. - pub log: Vec, - /// Messages prior to this snowflake were returned. - pub before: Option, -} - -/// Set the name you present to the room. -/// -/// This name applies to all messages sent during this session, until the nick -/// command is called again. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Nick { - /// The requested name (maximum length 36 bytes). - pub name: String, -} - -/// Confirms the [`Nick`] command. -/// -/// Returns the session's former and new names (the server may modify the -/// requested nick). -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NickReply { - /// The id of the session this name applies to. - pub session_id: String, - /// The id of the agent or account logged into the session. - pub id: UserId, - /// The previous name associated with the session. - pub from: String, - /// The name associated with the session henceforth. - pub to: String, -} - -/// Constructs a virtual room for private messaging between the client and the -/// given [`UserId`]. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PmInitiate { - /// The id of the user to invite to chat privately. - pub user_id: UserId, -} - -/// Provides the PMID for the requested private messaging room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PmInitiateReply { - /// The private chat can be accessed at `/room/pm:`. - pub pm_id: Snowflake, - /// The nickname of the recipient of the invitation. - pub to_nick: String, -} - -/// Send a message to a room. -/// -/// The session must be successfully joined with the room. This message will be -/// broadcast to all sessions joined with the room. -/// -/// If the room is private, then the message content will be encrypted before it -/// is stored and broadcast to the rest of the room. -/// -/// The caller of this command will not receive the corresponding -/// [`SendEvent`](super::SendEvent), but will receive the same information in -/// the [`SendReply`]. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Send { - /// The content of the message (client-defined). - pub content: String, - /// The id of the parent message, if any. - pub parent: Option, -} - -/// The message that was sent. -/// -/// this includes the message id, which was populated by the server. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SendReply(pub Message); - -/// Request a list of sessions currently joined in the room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Who; - -/// Lists the sessions currently joined in the room. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WhoReply { - /// A list of session views. - listing: Vec, -} diff --git a/src/euph/api/session_cmds.rs b/src/euph/api/session_cmds.rs deleted file mode 100644 index e169f7d..0000000 --- a/src/euph/api/session_cmds.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! Session commands. - -use serde::{Deserialize, Serialize}; - -use super::{AuthOption, Time}; - -/// Attempt to join a private room. -/// -/// This should be sent in response to a bounce event at the beginning of a -/// session. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Auth { - /// The method of authentication. - pub r#type: AuthOption, - /// Use this field for [`AuthOption::Passcode`] authentication. - pub passcode: Option, -} - -/// Reports whether the [`Auth`] command succeeded. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AuthReply { - /// True if authentication succeeded. - pub success: bool, - /// If [`Self::success`] was false, the reason for failure. - pub reason: Option, -} - -/// Initiate a client-to-server ping. -/// -/// The server will send back a [`PingReply`] with the same timestamp as soon as -/// possible. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Ping { - /// An arbitrary value, intended to be a unix timestamp. - pub time: Time, -} - -/// Response to a [`Ping`] command or [`PingEvent`](super::PingEvent). -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PingReply { - /// The timestamp of the ping being replied to. - pub time: Option