From aa710a3420ef4d834ee1df4099b25f3c83b9c31d Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Sat, 22 May 2021 01:27:17 +0200 Subject: rework command response mechanism --- mumctl/Cargo.toml | 1 + mumctl/src/main.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 9 deletions(-) (limited to 'mumctl') diff --git a/mumctl/Cargo.toml b/mumctl/Cargo.toml index fff2a1c..3467ffc 100644 --- a/mumctl/Cargo.toml +++ b/mumctl/Cargo.toml @@ -18,5 +18,6 @@ bincode = "1" colored = "2" log = "0.4" structopt = "0.3" +serde = "1" #cursive = "0.15" diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index 4e1249e..318aa3c 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -4,11 +4,13 @@ use mumlib::command::{Command as MumCommand, CommandResponse, MessageTarget}; use mumlib::config::{self, Config, ServerConfig}; use mumlib::state::Channel as MumChannel; use std::fmt; +use std::marker::PhantomData; use std::io::{self, BufRead, Read, Write}; use std::iter; use std::os::unix::net::UnixStream; use std::thread; use structopt::{clap::Shell, StructOpt}; +use serde::de::DeserializeOwned; const INDENTATION: &str = " "; @@ -88,8 +90,11 @@ enum Command { Deafen, /// Undeafen yourself Undeafen, - /// Get messages - Messages, + /// Get messages sent to the server you're currently connected to + Messages { + #[structopt(short = "i", long = "interactive")] + interactive: bool, + }, /// Send a message to a channel or a user Message(Target), } @@ -372,14 +377,15 @@ fn match_opt() -> Result<(), Error> { Command::Undeafen => { send_command(MumCommand::DeafenSelf(Some(false)))??; } - Command::Messages => { - match send_command(MumCommand::PastMessages { block: false })?? { - Some(CommandResponse::PastMessages { messages }) => { - for (msg, sender) in messages { - println!("{}: {}", sender, msg); - } + Command::Messages { + interactive + } => { + for response in send_command_multi(MumCommand::PastMessages { block: interactive })? { + match response { + Ok(Some(CommandResponse::PastMessage { message })) => println!("{}: {}", message.1, message.0), + Ok(_) => unreachable!("Response should only be a Some(PastMessages)"), + Err(e) => error!("{}", e), } - _ => unreachable!("Response should only be a PastMessages"), } } Command::Message(target) => { @@ -660,6 +666,54 @@ fn send_command( bincode::deserialize_from(&mut connection).map_err(|_| CliError::ConnectionError) } +fn send_command_multi( + command: MumCommand, +) -> Result>>, CliError> { + let mut connection = + UnixStream::connect(mumlib::SOCKET_PATH).map_err(|_| CliError::ConnectionError)?; + + let serialized = bincode::serialize(&command).unwrap(); + + connection + .write(&(serialized.len() as u32).to_be_bytes()) + .map_err(|_| CliError::ConnectionError)?; + connection + .write(&serialized) + .map_err(|_| CliError::ConnectionError)?; + + connection.shutdown(std::net::Shutdown::Write) + .map_err(|_| CliError::ConnectionError)?; + + Ok(BincodeIter::new(connection)) +} + +struct BincodeIter { + reader: R, + phantom: PhantomData<*const I>, +} + +impl BincodeIter { + fn new(reader: R) -> Self { + Self { + reader, + phantom: PhantomData, + } + } +} + +impl Iterator for BincodeIter + where R: Read, I: DeserializeOwned { + type Item = I; + + #[inline] + fn next(&mut self) -> Option { + self.reader + .read_exact(&mut [0; 4]) + .ok()?; + bincode::deserialize_from(&mut self.reader).ok() + } +} + fn print_channel(channel: &MumChannel, depth: usize) { println!( "{}{}{}", -- cgit v1.2.1