use crate::state::{Channel, Server}; use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use std::fmt; /// Something that happened in our channel at a point in time. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MumbleEvent { pub timestamp: NaiveDateTime, pub kind: MumbleEventKind } impl fmt::Display for MumbleEvent { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "[{}] {}", self.timestamp.format("%d %b %H:%M"), self.kind) } } /// The different kinds of events that can happen. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum MumbleEventKind { UserConnected(String, String), UserDisconnected(String, String), UserMuteStateChanged(String), // This logic is kinda weird so we only store the rendered message. TextMessageReceived(String), UserJoinedChannel(String, String), UserLeftChannel(String, String), } //TODO These strings are (mostly) duplicated with their respective notifications. // The only difference is that the text message event doesn't contain the text message. impl fmt::Display for MumbleEventKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { MumbleEventKind::UserConnected(user, channel) => { write!(f, "{} connected to {}", user, channel) } MumbleEventKind::UserDisconnected(user, channel) => { write!(f, "{} disconnected from {}", user, channel) } MumbleEventKind::UserMuteStateChanged(message) => { write!(f, "{}", message) } MumbleEventKind::TextMessageReceived(user) => { write!(f, "{} sent a text message", user) } MumbleEventKind::UserJoinedChannel(name, from) => { write!(f, "{} moved to your channel from {}", name, from) } MumbleEventKind::UserLeftChannel(name, to) => { write!(f, "{} moved to {}", name, to) } } } } #[derive(Clone, Debug, Deserialize, Serialize)] pub enum Command { ChannelJoin { channel_identifier: String, }, ChannelList, ConfigReload, DeafenSelf(Option), Events { block: bool }, InputVolumeSet(f32), MuteOther(String, Option), MuteSelf(Option), OutputVolumeSet(f32), PastMessages { block: bool, }, Ping, SendMessage { message: String, targets: MessageTarget, }, ServerConnect { host: String, port: u16, username: String, password: Option, accept_invalid_cert: bool, }, ServerDisconnect, ServerStatus { host: String, port: u16, }, Status, UserVolumeSet(String, f32), } #[derive(Debug, Deserialize, Serialize)] pub enum CommandResponse { ChannelList { channels: Channel, }, DeafenStatus { is_deafened: bool, }, Event { event: MumbleEvent, }, MuteStatus { is_muted: bool, }, PastMessage { message: (NaiveDateTime, String, String), }, Pong, ServerConnect { welcome_message: Option, server_state: Server, }, ServerStatus { version: u32, users: u32, max_users: u32, bandwidth: u32, }, Status { server_state: Server, }, } /// Messages sent to channels can be sent either to a named channel or the /// currently connected channel. #[derive(Clone, Debug, Deserialize, Serialize)] pub enum ChannelTarget { Current, Named(String) } /// Messages can be sent to either channels or specific users. #[derive(Clone, Debug, Deserialize, Serialize)] pub enum MessageTarget { Channel(Vec<(ChannelTarget, bool)>), // (target, recursive) User(Vec), }