From 71b581250ae614f67c7d02796de57142c68de1b2 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:15:38 +0200 Subject: [PATCH 01/28] make NcMessage a tuple struct --- src/backend/nc_message.rs | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index b7ef6a5..8fc99f7 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -2,66 +2,60 @@ use crate::backend::nc_request::NCReqDataMessage; use chrono::prelude::*; #[derive(Debug)] -pub struct NCMessage { - data: NCReqDataMessage, - message: String, -} +pub struct NCMessage(NCReqDataMessage); impl From for NCMessage { fn from(data: NCReqDataMessage) -> Self { - NCMessage { - message: data.message.clone(), - data, - } + NCMessage(data) } } impl NCMessage { pub fn get_time_str(&self) -> String { let time: DateTime = - DateTime::from(DateTime::::from_timestamp(self.data.timestamp, 0).unwrap()); + DateTime::from(DateTime::::from_timestamp(self.0.timestamp, 0).unwrap()); time.format("%H:%M").to_string() } pub fn get_name(&self) -> String { - self.data.actorDisplayName.clone() + self.0.actorDisplayName.clone() } - pub fn get_message(&self) -> String { - self.message.clone() + pub fn get_message(&self) -> &str { + &self.0.message } pub fn get_reactions_str(&self) -> String { let mut reactions = String::new(); - for (icon, number) in &self.data.reactions { + for (icon, number) in &self.0.reactions { reactions = reactions + "('" + icon + "' times " + &number.to_string() + "), "; } reactions } pub fn get_id(&self) -> i32 { - self.data.id + self.0.id } pub fn to_data(&self) -> NCReqDataMessage { - self.data.clone() + self.0.clone() } pub fn is_comment(&self) -> bool { - self.data.messageType == "comment" + self.0.messageType == "comment" } pub fn is_comment_deleted(&self) -> bool { - self.data.messageType == "comment_deleted" + self.0.messageType == "comment_deleted" } pub fn is_system(&self) -> bool { - self.data.messageType == "system" + self.0.messageType == "system" } pub fn is_edit_note(&self) -> bool { if self.is_system() { - self.data.systemMessage == "message_edited" + self.0.systemMessage == "message_edited" } else { false } @@ -69,17 +63,17 @@ impl NCMessage { pub fn is_reaction(&self) -> bool { if self.is_system() { - self.data.systemMessage == "reaction" + self.0.systemMessage == "reaction" } else { false } } pub fn is_command(&self) -> bool { - self.data.messageType == "command" + self.0.messageType == "command" } pub fn has_reactions(&self) -> bool { - !self.data.reactions.is_empty() + !self.0.reactions.is_empty() } } From 528dde9b27b77d8c1cdf7f6803277600783fed68 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:20:36 +0200 Subject: [PATCH 02/28] remove mut and for --- src/backend/nc_message.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index 8fc99f7..b06d2ea 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -26,11 +26,14 @@ impl NCMessage { } pub fn get_reactions_str(&self) -> String { - let mut reactions = String::new(); - for (icon, number) in &self.0.reactions { - reactions = reactions + "('" + icon + "' times " + &number.to_string() + "), "; - } - reactions + self.0 + .reactions + .iter() + .map(|(icon, number)| format!("('{icon}' times {}), ", &number.to_string())) + .collect::>() + .join(", ") + // TODO: this was in previous code! is this comma at the end needed? + + ", " } pub fn get_id(&self) -> i32 { From 2029decabd589c0aec08f5909beca6f1c73c856f Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:22:11 +0200 Subject: [PATCH 03/28] remove some redundant ifs --- src/backend/nc_message.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index b06d2ea..b449968 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -57,19 +57,11 @@ impl NCMessage { } pub fn is_edit_note(&self) -> bool { - if self.is_system() { - self.0.systemMessage == "message_edited" - } else { - false - } + self.is_system() && self.0.systemMessage == "message_edited" } pub fn is_reaction(&self) -> bool { - if self.is_system() { - self.0.systemMessage == "reaction" - } else { - false - } + self.is_system() && self.0.systemMessage == "reaction" } pub fn is_command(&self) -> bool { From bc3b7bed72e79ab84d3d327bb4fe9949021e44ad Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:23:49 +0200 Subject: [PATCH 04/28] remove unwrap with expect to give a hint in case --- src/backend/nc_message.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index b449968..fb3db91 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -12,8 +12,10 @@ impl From for NCMessage { impl NCMessage { pub fn get_time_str(&self) -> String { - let time: DateTime = - DateTime::from(DateTime::::from_timestamp(self.0.timestamp, 0).unwrap()); + let time: DateTime = DateTime::from( + DateTime::::from_timestamp(self.0.timestamp, 0) + .expect("cannot convert UTC time stamp"), + ); time.format("%H:%M").to_string() } From 9bdd7e92b3bb992caa05f8aff7edc8d6f6f2e7c5 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:35:10 +0200 Subject: [PATCH 05/28] remove mut and for and rename to_data() --- src/backend/nc_message.rs | 2 +- src/backend/nc_room.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index fb3db91..27e46a2 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -42,7 +42,7 @@ impl NCMessage { self.0.id } - pub fn to_data(&self) -> NCReqDataMessage { + pub fn clone_data(&self) -> NCReqDataMessage { self.0.clone() } diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index a781e7b..438185f 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -230,11 +230,8 @@ impl NCRoom { } pub fn write_to_log(&mut self) -> Result<(), std::io::Error> { - let mut data = Vec::::new(); + let data: Vec<_> = self.messages.iter().map(NCMessage::clone_data).collect(); let path = self.path_to_log.as_path(); - for message in &mut self.messages { - data.push(message.to_data()); - } // Open a file in write-only mode, returns `io::Result` let mut file = match File::create(path) { Err(why) => { From 0ab02c5105a11168c81feee1a044342be0a9d83e Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:37:10 +0200 Subject: [PATCH 06/28] return reference --- src/backend/nc_message.rs | 4 ++-- src/ui/chat_box.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index 27e46a2..a0d89c7 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -19,8 +19,8 @@ impl NCMessage { time.format("%H:%M").to_string() } - pub fn get_name(&self) -> String { - self.0.actorDisplayName.clone() + pub fn get_name(&self) -> &str { + &self.0.actorDisplayName } pub fn get_message(&self) -> &str { diff --git a/src/ui/chat_box.rs b/src/ui/chat_box.rs index 45250c1..d95ea33 100644 --- a/src/ui/chat_box.rs +++ b/src/ui/chat_box.rs @@ -46,7 +46,7 @@ impl<'a> ChatBox<'a> { }) { let name = textwrap::wrap( - &message_data.get_name(), + message_data.get_name(), Options::new(NAME_WIDTH.into()).break_words(true), ) .into_iter() From eafce25bfc8391859f46fe80987ccbacc5d73310 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:38:18 +0200 Subject: [PATCH 07/28] use derive Default --- src/backend/nc_notify.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/backend/nc_notify.rs b/src/backend/nc_notify.rs index e8c878f..29611d4 100644 --- a/src/backend/nc_notify.rs +++ b/src/backend/nc_notify.rs @@ -1,7 +1,7 @@ use crate::config::{self}; use notify_rust::{Hint, Notification, Timeout}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct NCNotify { app_name: String, timeout_ms: u32, @@ -64,9 +64,3 @@ impl NCNotify { Ok(()) } } - -impl Default for NCNotify { - fn default() -> Self { - Self::new() - } -} From 37333ab95941d341fd61b293b29d0fc1e4d6d0e1 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:43:48 +0200 Subject: [PATCH 08/28] improve readability --- src/backend/nc_request.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/backend/nc_request.rs b/src/backend/nc_request.rs index 73a2861..a0e77c7 100644 --- a/src/backend/nc_request.rs +++ b/src/backend/nc_request.rs @@ -245,10 +245,14 @@ pub struct NCReqOCS { impl NCRequest { pub fn new() -> Result> { - let username = config::get().data.general.user.clone(); - let password = Some(config::get().data.general.app_pw.clone()); - let base_url = config::get().data.general.url.clone(); - let json_dump_path = config::get().get_http_dump_dir(); + let config = &config::get(); + let general = &config.data.general; + + let username = general.user.clone(); + let password = Some(general.app_pw.clone()); + let base_url = general.url.clone(); + + let json_dump_path = config.get_http_dump_dir(); let mut headers = header::HeaderMap::new(); headers.insert("OCS-APIRequest", header::HeaderValue::from_static("true")); headers.insert( @@ -259,9 +263,9 @@ impl NCRequest { let mut buf = b"Basic ".to_vec(); { let mut encoder = EncoderWriter::new(&mut buf, &BASE64_STANDARD); - let _ = write!(encoder, "{username}:"); + write!(encoder, "{username}:").expect("i/o error"); if let Some(password) = password { - let _ = write!(encoder, "{password}"); + write!(encoder, "{password}").expect("i/o error"); } } let mut auth_value = From 11fda13b565decd037fa74f6d2c704758cfe8927 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 16:56:04 +0200 Subject: [PATCH 09/28] unify reqwest usage --- src/backend/nc_request.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/backend/nc_request.rs b/src/backend/nc_request.rs index a0e77c7..96548c7 100644 --- a/src/backend/nc_request.rs +++ b/src/backend/nc_request.rs @@ -4,8 +4,10 @@ use base64::{prelude::BASE64_STANDARD, write::EncoderWriter}; use jzon; -use reqwest::header::HeaderMap; -use reqwest::{header, Client, Response, Url}; +use reqwest::{ + header::{HeaderMap, HeaderValue, AUTHORIZATION}, + Client, Response, Url, +}; use serde::{Deserialize, Deserializer, Serialize}; use std::path::PathBuf; use std::{collections::HashMap, error::Error, fs::File, io::Write}; @@ -253,12 +255,9 @@ impl NCRequest { let base_url = general.url.clone(); let json_dump_path = config.get_http_dump_dir(); - let mut headers = header::HeaderMap::new(); - headers.insert("OCS-APIRequest", header::HeaderValue::from_static("true")); - headers.insert( - "Accept", - header::HeaderValue::from_static("application/json"), - ); + let mut headers = HeaderMap::new(); + headers.insert("OCS-APIRequest", HeaderValue::from_static("true")); + headers.insert("Accept", HeaderValue::from_static("application/json")); let mut buf = b"Basic ".to_vec(); { @@ -269,9 +268,9 @@ impl NCRequest { } } let mut auth_value = - header::HeaderValue::from_bytes(&buf).expect("base64 is always valid HeaderValue"); + HeaderValue::from_bytes(&buf).expect("base64 is always valid HeaderValue"); auth_value.set_sensitive(true); - headers.insert(header::AUTHORIZATION, auth_value); + headers.insert(AUTHORIZATION, auth_value); // get a client builder let client = reqwest::Client::builder() From 69d92237ba9b7814b2e029b15f3fc87f0e7da039 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 17:13:39 +0200 Subject: [PATCH 10/28] remove further mutables --- src/backend/nc_request.rs | 53 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/backend/nc_request.rs b/src/backend/nc_request.rs index 96548c7..d7611de 100644 --- a/src/backend/nc_request.rs +++ b/src/backend/nc_request.rs @@ -291,8 +291,7 @@ impl NCRequest { token: &str, ) -> Result> { let url_string = self.base_url.clone() + "/ocs/v2.php/apps/spreed/api/v1/chat/" + token; - let mut params = HashMap::new(); - params.insert("message".to_owned(), message.clone()); + let params = HashMap::from([("message", message)]); let url = Url::parse_with_params(&url_string, params)?; let response = self.request_post(url).await?; @@ -316,13 +315,10 @@ impl NCRequest { name: &str, ) -> Result, Box> { let url_string = self.base_url.clone() + "/ocs/v2.php/core/autocomplete/get"; - let mut params = HashMap::new(); - params.insert("limit".to_owned(), "200".to_string()); - params.insert("search".to_owned(), name.to_string()); - + let params = HashMap::from([("limit", "200"), ("search", name)]); let url = Url::parse_with_params(&url_string, params)?; - let response = self.request(url).await?; + match response.status() { reqwest::StatusCode::OK => { let text = response.text().await?; @@ -352,8 +348,7 @@ impl NCRequest { + "/ocs/v2.php/apps/spreed/api/v4/room/" + token + "/participants"; - let mut params = HashMap::new(); - params.insert("includeStatus".to_owned(), "true".to_string()); + let params = HashMap::from([("includeStatus", "true")]); let url = Url::parse_with_params(&url_string, params)?; let response = self.request(url).await?; @@ -394,10 +389,11 @@ impl NCRequest { last_timestamp: Option, ) -> Result<(Vec, i64), Box> { let url_string = self.base_url.clone() + "/ocs/v2.php/apps/spreed/api/v4/room"; - let mut params = HashMap::new(); - if let Some(timestamp) = last_timestamp { - params.insert("modifiedSince".to_owned(), timestamp.to_string()); - } + let params = if let Some(timestamp) = last_timestamp { + HashMap::from([("modifiedSince", timestamp.to_string())]) + } else { + HashMap::new() + }; let url = Url::parse_with_params(&url_string, ¶ms)?; let response = self.request(url).await?; match response.status() { @@ -466,18 +462,23 @@ impl NCRequest { last_message: Option, ) -> Result>, Box> { let url_string = self.base_url.clone() + "/ocs/v2.php/apps/spreed/api/v1/chat/" + token; - let mut params = HashMap::new(); - params.insert("limit".to_owned(), maxMessage.to_string()); - params.insert("setReadMarker".to_owned(), "0".to_owned()); - if let Some(lastId) = last_message { + let params = if let Some(lastId) = last_message { log::debug!("Last MessageID {}", lastId); - params.insert("lastKnownMessageId".to_owned(), lastId.to_string()); - params.insert("lookIntoFuture".to_owned(), "1".to_owned()); - params.insert("timeout".to_owned(), "0".to_owned()); - params.insert("includeLastKnown".to_owned(), "0".to_owned()); + HashMap::from([ + ("limit", maxMessage.to_string()), + ("setReadMarker", "0".into()), + ("lookIntoFuture", "1".to_owned()), + ("lastKnownMessageId", lastId.to_string()), + ("timeout", "0".to_owned()), + ("includeLastKnown", "0".to_owned()), + ]) } else { - params.insert("lookIntoFuture".to_owned(), "0".to_owned()); - } + HashMap::from([ + ("limit", maxMessage.to_string()), + ("setReadMarker", "0".into()), + ("lookIntoFuture", "0".into()), + ]) + }; let url = Url::parse_with_params(&url_string, ¶ms)?; let response = self.request(url).await?; match response.status() { @@ -542,8 +543,10 @@ impl NCRequest { fn dump_json_to_log(&self, url: &str, text: &str) -> Result<(), Box> { if let Some(path) = &self.json_dump_path { - let mut name = path.clone(); - name.push(url.replace('/', "_")); + let name: String = url + .chars() + .map(|ch| if ch == '/' { '_' } else { ch }) + .collect(); let mut file = File::create(name)?; let pretty_text = jzon::stringify_pretty(jzon::parse(text)?, 2); file.write_all(pretty_text.as_bytes())?; From de37fb0f17d11ec0c15a95f7ac6836c333905822 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 17:32:11 +0200 Subject: [PATCH 11/28] remove for loop --- src/backend/nc_talk.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/backend/nc_talk.rs b/src/backend/nc_talk.rs index 299cd99..8d9ace9 100644 --- a/src/backend/nc_talk.rs +++ b/src/backend/nc_talk.rs @@ -35,15 +35,14 @@ impl NCTalk { rooms: &mut HashMap, chat_log_path: PathBuf, ) { - let mut v = Vec::new(); - for child in response { - v.push(tokio::spawn(NCTalk::new_room( + let v = response.into_iter().map(|child| { + tokio::spawn(NCTalk::new_room( child, requester.clone(), notifier.clone(), chat_log_path.clone(), - ))); - } + )) + }); for jh in v { let (name, room_option) = jh.await.unwrap(); if let Some(room) = room_option { From 818a1c80e1708f7af31b567fe5a9ea44fff70e9c Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 17:45:09 +0200 Subject: [PATCH 12/28] remove mut and for --- src/backend/nc_room.rs | 2 +- src/backend/nc_talk.rs | 30 ++++++++++++++++-------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index 438185f..ca04542 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -14,7 +14,7 @@ use std::{ path::PathBuf, }; -#[derive(Debug, FromPrimitive)] +#[derive(Debug, FromPrimitive, PartialEq)] pub enum NCRoomTypes { OneToOne = 1, Group, diff --git a/src/backend/nc_talk.rs b/src/backend/nc_talk.rs index 8d9ace9..c2e4886 100644 --- a/src/backend/nc_talk.rs +++ b/src/backend/nc_talk.rs @@ -250,20 +250,22 @@ impl NCTalk { } pub fn get_dm_keys_display_name_mapping(&self) -> Vec<(String, String)> { - let mut mapping: Vec<(String, String)> = Vec::new(); - for (key, room) in &self.rooms { - match room.room_type { - NCRoomTypes::OneToOne | NCRoomTypes::NoteToSelf | NCRoomTypes::ChangeLog => { - mapping.push((key.clone(), self.rooms[key].to_string())); - } - _ => {} - } - } - mapping.sort_by(|(token_a, _), (token_b, _)| { - self.get_room_by_token(token_a) - .cmp(self.get_room_by_token(token_b)) - }); - mapping + self.rooms + .iter() + .filter(|(_, room)| { + [ + NCRoomTypes::OneToOne, + NCRoomTypes::NoteToSelf, + NCRoomTypes::ChangeLog, + ] + .contains(&room.room_type) + }) + .map(|(key, _)| (key.clone(), self.rooms[key].to_string())) + .sorted_by(|(token_a, _), (token_b, _)| { + self.get_room_by_token(token_a) + .cmp(self.get_room_by_token(token_b)) + }) + .collect_vec() } pub fn get_group_keys_display_name_mapping(&self) -> Vec<(String, String)> { From 248a90c262832c289e4d390e18db1119b017d99f Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Wed, 28 Aug 2024 17:52:12 +0200 Subject: [PATCH 13/28] replace for loop --- src/backend/nc_room.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index ca04542..0307fb1 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -66,9 +66,7 @@ impl NCRoom { if let Ok(data) = serde_json::from_str::>( read_to_string(path).unwrap().as_str(), ) { - for message in data { - messages.push(message.into()); - } + messages.extend(data.into_iter().map(Into::into)); } else { log::debug!( "Failed to parse json for {}, falling back to fetching", From 1b4118078b09a47b41b380e4fb1ccf66ea20abfc Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:06:13 +0200 Subject: [PATCH 14/28] remove following comma --- src/backend/nc_message.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index a0d89c7..e02195b 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -34,8 +34,6 @@ impl NCMessage { .map(|(icon, number)| format!("('{icon}' times {}), ", &number.to_string())) .collect::>() .join(", ") - // TODO: this was in previous code! is this comma at the end needed? - + ", " } pub fn get_id(&self) -> i32 { From 090fd6febc5b981e58b84354de25b3cf1a610f0c Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:13:19 +0200 Subject: [PATCH 15/28] simplified conversions --- src/backend/nc_request.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/nc_request.rs b/src/backend/nc_request.rs index d7611de..c23dc2b 100644 --- a/src/backend/nc_request.rs +++ b/src/backend/nc_request.rs @@ -467,10 +467,10 @@ impl NCRequest { HashMap::from([ ("limit", maxMessage.to_string()), ("setReadMarker", "0".into()), - ("lookIntoFuture", "1".to_owned()), + ("lookIntoFuture", "1".into()), ("lastKnownMessageId", lastId.to_string()), - ("timeout", "0".to_owned()), - ("includeLastKnown", "0".to_owned()), + ("timeout", "0".into()), + ("includeLastKnown", "0".into()), ]) } else { HashMap::from([ From 0c75e92b26d3cbb6258b59522f030b6ad3a3711c Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:18:22 +0200 Subject: [PATCH 16/28] remove mut --- src/ui/chat_box.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ui/chat_box.rs b/src/ui/chat_box.rs index d95ea33..b849144 100644 --- a/src/ui/chat_box.rs +++ b/src/ui/chat_box.rs @@ -53,7 +53,6 @@ impl<'a> ChatBox<'a> { .map(std::borrow::Cow::into_owned) .map(Line::from) .collect_vec(); - let mut row_height: u16 = name.len().try_into().unwrap(); let message_string = message_data .get_message() @@ -66,8 +65,11 @@ impl<'a> ChatBox<'a> { .collect_vec() }) .collect_vec(); - if message_string.len() > row_height as usize { - row_height = message_string.len().try_into().unwrap(); + + let row_height: u16 = if message_string.len() > name.len() { + message_string.len().try_into().expect("message too long") + } else { + name.len().try_into().expect("name too long") }; let message: Vec = vec![ message_data.get_time_str().into(), From 0e5c0c335e2bcc98d7441b5af2ded8d31d069893 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:20:58 +0200 Subject: [PATCH 17/28] typo in UI --- src/ui/help_box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/help_box.rs b/src/ui/help_box.rs index c73fd76..43143ab 100644 --- a/src/ui/help_box.rs +++ b/src/ui/help_box.rs @@ -49,7 +49,7 @@ impl Widget for &HelpBox { ) .column_spacing(1) .style(Style::new().white().on_black()) - .header(Row::new(vec!["Key", "Name", "Behaviour"]).style(Style::new().bold().blue())) + .header(Row::new(vec!["Key", "Name", "Behavior"]).style(Style::new().bold().blue())) .block(Block::default()) .highlight_style(Style::new().green()) .highlight_spacing(HighlightSpacing::Never), From 118c152118d1aedb710798630f527340b0bc6561 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:29:21 +0200 Subject: [PATCH 18/28] cleaned usages --- src/ui/mod.rs | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index d2ebb97..263c56e 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -7,32 +7,26 @@ pub mod title_bar; use super::{ backend::nc_talk::NCTalk, - config::{self}, + config, ui::app::{App, CurrentScreen}, }; use cfg_if::cfg_if; use color_eyre::{ config::{EyreHook, HookBuilder, PanicHook}, - eyre::{self, Result}, + eyre, }; use crossterm::{ event::{ - self, DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture, - Event, KeyCode, KeyEventKind, KeyModifiers, MouseEventKind, + poll, read, DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, + EnableMouseCapture, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseEventKind, }, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use ratatui::prelude::*; -use std::{ - error::Error, - io::{stdout, Stdout}, - panic, - time::Duration, -}; use tracing::error; -pub fn install_hooks() -> Result<()> { +pub fn install_hooks() -> eyre::Result<()> { let (panic_hook, eyre_hook) = HookBuilder::default() .panic_section(format!( "This is a bug. Consider reporting it at {}", @@ -68,7 +62,7 @@ fn install_color_eyre_panic_hook(panic_hook: PanicHook) { // convert from a `color_eyre::config::PanicHook`` to a `Box` let panic_hook = panic_hook.into_panic_hook(); - panic::set_hook(Box::new(move |panic_info| { + std::panic::set_hook(Box::new(move |panic_info| { if let Err(err) = restore() { error!("Unable to restore terminal: {err:?}"); } @@ -89,9 +83,11 @@ fn install_eyre_hook(eyre_hook: EyreHook) -> color_eyre::Result<()> { Ok(()) } -pub type Tui = Terminal>; +pub type Tui = Terminal>; + +pub fn init() -> eyre::Result { + use std::io::stdout; -pub fn init() -> Result { enable_raw_mode()?; execute!(stdout(), EnterAlternateScreen)?; if config::get().get_enable_mouse() { @@ -106,7 +102,9 @@ pub fn init() -> Result { Ok(terminal) } -pub fn restore() -> Result<()> { +pub fn restore() -> eyre::Result<()> { + use std::io::stdout; + if config::get().get_enable_paste() { execute!(stdout(), DisableBracketedPaste)?; } @@ -123,7 +121,7 @@ enum ProcessEventResult { Exit, } -pub async fn run(nc_backend: NCTalk) -> Result<(), Box> { +pub async fn run(nc_backend: NCTalk) -> Result<(), Box> { install_hooks()?; // create app and run it @@ -140,15 +138,15 @@ pub async fn run(nc_backend: NCTalk) -> Result<(), Box> { async fn run_app( mut terminal: Terminal, mut app: App<'_>, -) -> Result<(), Box> { +) -> Result<(), Box> { app.select_room().await?; log::debug!("Entering Main Loop"); loop { terminal.draw(|f| app.ui(f))?; // Event within timeout? - if event::poll(Duration::from_millis(3000))? { - match process_event(&mut app, event::read()?).await { + if poll(std::time::Duration::from_millis(3000))? { + match process_event(&mut app, read()?).await { Ok(ProcessEventResult::Continue) => (), Ok(ProcessEventResult::Exit) => return Ok(()), Err(why) => return Err(why), @@ -164,11 +162,11 @@ async fn run_app( async fn process_event( app: &mut App<'_>, event: Event, -) -> Result> { +) -> Result> { // It's guaranteed that `read` won't block, because `poll` returned // `Ok(true)`. match event { - Event::Key(key) if key.kind != event::KeyEventKind::Release => { + Event::Key(key) if key.kind != KeyEventKind::Release => { log::debug!("Processing key event {:?}", key.code); match app.current_screen { CurrentScreen::Helping => handle_key_in_help(key, app), @@ -196,9 +194,9 @@ async fn process_event( } async fn handle_key_in_opening( - key: event::KeyEvent, + key: KeyEvent, app: &mut App<'_>, -) -> Result<(), Box> { +) -> Result<(), Box> { match key.code { KeyCode::Esc => app.current_screen = CurrentScreen::Reading, KeyCode::Char('h') | KeyCode::Left => _ = app.selector.state.key_left(), @@ -219,9 +217,9 @@ async fn handle_key_in_opening( } async fn handle_key_in_editing( - key: event::KeyEvent, + key: KeyEvent, app: &mut App<'_>, -) -> Result<(), Box> { +) -> Result<(), Box> { if key.kind == KeyEventKind::Press { match key.code { KeyCode::Enter => { @@ -239,7 +237,7 @@ async fn handle_key_in_editing( Ok(()) } -fn handle_key_in_help(key: event::KeyEvent, app: &mut App) { +fn handle_key_in_help(key: KeyEvent, app: &mut App) { match key.code { KeyCode::Char('q') => app.current_screen = CurrentScreen::Exiting, KeyCode::Esc => app.current_screen = CurrentScreen::Reading, @@ -249,9 +247,9 @@ fn handle_key_in_help(key: event::KeyEvent, app: &mut App) { } fn handle_key_in_exit( - key: event::KeyEvent, + key: KeyEvent, app: &mut App, -) -> Option>> { +) -> Option>> { match key.code { KeyCode::Char('?') => app.current_screen = CurrentScreen::Helping, KeyCode::Char('y') => { @@ -270,9 +268,9 @@ fn handle_key_in_exit( } async fn handle_key_in_reading( - key: event::KeyEvent, + key: KeyEvent, app: &mut App<'_>, -) -> Result<(), Box> { +) -> Result<(), Box> { match key.code { KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => { app.current_screen = CurrentScreen::Exiting; From ed8ad0fe5887ce1d500435efe8a938e854c7e44a Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:41:04 +0200 Subject: [PATCH 19/28] remove high level std usages --- src/ui/app.rs | 13 ++++++------- src/ui/chat_box.rs | 4 ++-- src/ui/title_bar.rs | 1 - 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/ui/app.rs b/src/ui/app.rs index 904e2fc..7550008 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -6,7 +6,6 @@ use crate::{ }, }; use ratatui::{prelude::*, widgets::Paragraph}; -use std::error::Error; use strum_macros::Display; #[derive(PartialEq, Clone, Copy, Display)] @@ -82,21 +81,21 @@ impl<'a> App<'a> { self.title.render_area(f, base_layout[0]); } - pub async fn mark_current_as_read(&mut self) -> Result<(), Box> { + pub async fn mark_current_as_read(&mut self) -> Result<(), Box> { self.backend.get_current_room().mark_as_read().await?; self.backend.update_rooms(true).await?; self.update_ui()?; Ok(()) } - fn update_ui(&mut self) -> Result<(), Box> { + fn update_ui(&mut self) -> Result<(), Box> { self.title.update(self.current_screen, &self.backend); self.selector.update(&self.backend)?; self.chat.update_messages(&self.backend); Ok(()) } - pub async fn send_message(&mut self) -> Result<(), Box> { + pub async fn send_message(&mut self) -> Result<(), Box> { self.backend.send_message(self.input.to_string()).await?; self.input.clear(); self.update_ui()?; @@ -104,7 +103,7 @@ impl<'a> App<'a> { Ok(()) } - pub async fn select_room(&mut self) -> Result<(), Box> { + pub async fn select_room(&mut self) -> Result<(), Box> { if self.selector.state.selected().len() == 2 { self.backend .select_room( @@ -125,7 +124,7 @@ impl<'a> App<'a> { Ok(()) } - pub async fn fetch_updates(&mut self) -> Result<(), Box> { + pub async fn fetch_updates(&mut self) -> Result<(), Box> { self.backend.update_rooms(false).await?; self.update_ui()?; Ok(()) @@ -147,7 +146,7 @@ impl<'a> App<'a> { self.chat.select_down(); } - pub fn click_at(&mut self, position: Position) -> Result<(), Box> { + pub fn click_at(&mut self, position: Position) -> Result<(), Box> { match self.current_screen { CurrentScreen::Reading => self.chat.select_line(position)?, CurrentScreen::Opening => { diff --git a/src/ui/chat_box.rs b/src/ui/chat_box.rs index b849144..15c7151 100644 --- a/src/ui/chat_box.rs +++ b/src/ui/chat_box.rs @@ -3,7 +3,6 @@ use ratatui::{ prelude::*, widgets::{Block, Cell, HighlightSpacing, Row, Table, TableState}, }; -use std::{convert::TryInto, error::Error}; use textwrap::Options; // this fits my name, so 20 it is :D @@ -38,6 +37,7 @@ impl<'a> ChatBox<'a> { pub fn update_messages(&mut self, backend: &NCTalk) { use itertools::Itertools; + use std::convert::TryInto; self.messages.clear(); for message_data in @@ -128,7 +128,7 @@ impl<'a> ChatBox<'a> { .clamp(0, self.messages.len() - 1); self.state.select(Some(self.current_index)); } - pub fn select_line(&mut self, position: Position) -> Result<(), Box> { + pub fn select_line(&mut self, position: Position) -> Result<(), Box> { log::debug!( "Got Position {:?} and selected {:?}", position, diff --git a/src/ui/title_bar.rs b/src/ui/title_bar.rs index 6bd5d3e..5e88668 100644 --- a/src/ui/title_bar.rs +++ b/src/ui/title_bar.rs @@ -4,7 +4,6 @@ use ratatui::{ prelude::*, widgets::{Block, Borders, Paragraph}, }; -use std::string::ToString; use style::Styled; pub struct TitleBar<'a> { From 0b4dc3efb41895e8c4a8729daabca07e08f37d06 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:50:47 +0200 Subject: [PATCH 20/28] lock config once --- src/backend/nc_notify.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/backend/nc_notify.rs b/src/backend/nc_notify.rs index 29611d4..934a2c3 100644 --- a/src/backend/nc_notify.rs +++ b/src/backend/nc_notify.rs @@ -11,11 +11,12 @@ pub struct NCNotify { impl NCNotify { pub fn new() -> Self { + let data = &config::get().data; NCNotify { - app_name: config::get().data.general.chat_server_name.clone(), - timeout_ms: config::get().data.notifications.timeout_ms, - persistent: config::get().data.notifications.persistent, - silent: config::get().data.notifications.silent, + app_name: data.general.chat_server_name.clone(), + timeout_ms: data.notifications.timeout_ms, + persistent: data.notifications.persistent, + silent: data.notifications.silent, } } From 32b68c1e1a111ebdee78404962a5fd54a3335537 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 00:52:16 +0200 Subject: [PATCH 21/28] shorten as_str() --- src/backend/nc_notify.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/backend/nc_notify.rs b/src/backend/nc_notify.rs index 934a2c3..3711345 100644 --- a/src/backend/nc_notify.rs +++ b/src/backend/nc_notify.rs @@ -26,10 +26,12 @@ impl NCNotify { number_of_unread: usize, ) -> Result<(), Box> { let mut notification = Notification::new() - .summary(format!("Unread: {room_name}").as_str()) - .body(format!("You have {number_of_unread} new Messages in {room_name}").as_str()) + .summary(&format!("Unread: {room_name}")) + .body(&format!( + "You have {number_of_unread} new Messages in {room_name}" + )) .icon("dialog-information") - .appname(self.app_name.as_str()) + .appname(&self.app_name) .to_owned(); if self.persistent { log::debug!("Persistent Message!"); @@ -47,10 +49,10 @@ impl NCNotify { pub fn new_room(&self, room_name: &String) -> Result<(), Box> { let mut notification = Notification::new() - .summary(format!("New Room: {room_name}").as_str()) - .body(format!("You have been added to a new Room {room_name}").as_str()) + .summary(&format!("New Room: {room_name}")) + .body(&format!("You have been added to a new Room {room_name}")) .icon("dialog-information") - .appname(self.app_name.as_str()) + .appname(&self.app_name) .to_owned(); if self.persistent { notification From c5f80ebce081fcb858b5d1b794a28b4b99054e21 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 01:04:47 +0200 Subject: [PATCH 22/28] remove clone --- src/backend/nc_message.rs | 5 +++-- src/backend/nc_room.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index e02195b..d5db4fe 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -40,8 +40,9 @@ impl NCMessage { self.0.id } - pub fn clone_data(&self) -> NCReqDataMessage { - self.0.clone() + /// return inner data message + pub fn data(&self) -> &NCReqDataMessage { + &self.0 } pub fn is_comment(&self) -> bool { diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index 0307fb1..edc5cc0 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -228,7 +228,7 @@ impl NCRoom { } pub fn write_to_log(&mut self) -> Result<(), std::io::Error> { - let data: Vec<_> = self.messages.iter().map(NCMessage::clone_data).collect(); + let data: Vec<_> = self.messages.iter().map(NCMessage::data).collect(); let path = self.path_to_log.as_path(); // Open a file in write-only mode, returns `io::Result` let mut file = match File::create(path) { From 14d8c181e40a4f1a04b595996ade7b7941e745b0 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 01:24:01 +0200 Subject: [PATCH 23/28] remove redundant flag `persistent` --- src/backend/nc_notify.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/backend/nc_notify.rs b/src/backend/nc_notify.rs index 3711345..8e4396c 100644 --- a/src/backend/nc_notify.rs +++ b/src/backend/nc_notify.rs @@ -4,8 +4,7 @@ use notify_rust::{Hint, Notification, Timeout}; #[derive(Debug, Clone, Default)] pub struct NCNotify { app_name: String, - timeout_ms: u32, - persistent: bool, + timeout: Timeout, silent: bool, } @@ -14,8 +13,11 @@ impl NCNotify { let data = &config::get().data; NCNotify { app_name: data.general.chat_server_name.clone(), - timeout_ms: data.notifications.timeout_ms, - persistent: data.notifications.persistent, + timeout: if data.notifications.persistent { + Timeout::Never + } else { + Timeout::Milliseconds(data.notifications.timeout_ms) + }, silent: data.notifications.silent, } } @@ -33,14 +35,12 @@ impl NCNotify { .icon("dialog-information") .appname(&self.app_name) .to_owned(); - if self.persistent { + if self.is_persistent() { log::debug!("Persistent Message!"); - notification - .hint(Hint::Resident(true)) // this is not supported by all implementations - .timeout(Timeout::Never); // this however is - } else { - notification.timeout(Timeout::Milliseconds(self.timeout_ms)); } + notification + .hint(Hint::Resident(self.is_persistent())) // this is not supported by all implementations + .timeout(self.timeout); notification.hint(Hint::SuppressSound(self.silent)); notification.show()?; @@ -54,16 +54,17 @@ impl NCNotify { .icon("dialog-information") .appname(&self.app_name) .to_owned(); - if self.persistent { - notification - .hint(Hint::Resident(true)) // this is not supported by all implementations - .timeout(Timeout::Never); // this however is - } else { - notification.timeout(Timeout::Milliseconds(self.timeout_ms)); - } + notification + .hint(Hint::Resident(self.is_persistent())) // this is not supported by all implementations + .timeout(self.timeout); // this however is notification.hint(Hint::SuppressSound(self.silent)); notification.show()?; Ok(()) } + + /// return `true` if notification is persistent (has infinite display timeout) + pub fn is_persistent(&self) -> bool { + self.timeout == Timeout::Never + } } From e7e4d84773de0d1e0bd8bd1f098e6361238d3c06 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 01:24:13 +0200 Subject: [PATCH 24/28] add doc comments --- src/backend/nc_message.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/backend/nc_message.rs b/src/backend/nc_message.rs index d5db4fe..a4c2225 100644 --- a/src/backend/nc_message.rs +++ b/src/backend/nc_message.rs @@ -1,6 +1,7 @@ use crate::backend::nc_request::NCReqDataMessage; use chrono::prelude::*; +/// `NextCloud` message interface #[derive(Debug)] pub struct NCMessage(NCReqDataMessage); @@ -11,6 +12,7 @@ impl From for NCMessage { } impl NCMessage { + /// return message time stamp as string pub fn get_time_str(&self) -> String { let time: DateTime = DateTime::from( DateTime::::from_timestamp(self.0.timestamp, 0) @@ -19,14 +21,17 @@ impl NCMessage { time.format("%H:%M").to_string() } + /// return opponent display name pub fn get_name(&self) -> &str { &self.0.actorDisplayName } + /// return the message itself pub fn get_message(&self) -> &str { &self.0.message } + /// get list of reactions as comma separated string pub fn get_reactions_str(&self) -> String { self.0 .reactions @@ -36,6 +41,7 @@ impl NCMessage { .join(", ") } + /// get message identifier pub fn get_id(&self) -> i32 { self.0.id } @@ -45,30 +51,37 @@ impl NCMessage { &self.0 } + /// return `true` if message is a comment pub fn is_comment(&self) -> bool { self.0.messageType == "comment" } + /// return `true` if message is a deleted comment pub fn is_comment_deleted(&self) -> bool { self.0.messageType == "comment_deleted" } + /// return `true` if message is a system message pub fn is_system(&self) -> bool { self.0.messageType == "system" } + /// return `true` if message is an edited message pub fn is_edit_note(&self) -> bool { self.is_system() && self.0.systemMessage == "message_edited" } + /// return `true` if message is a reaction pub fn is_reaction(&self) -> bool { self.is_system() && self.0.systemMessage == "reaction" } + /// return `true` if message is a command pub fn is_command(&self) -> bool { self.0.messageType == "command" } + /// return `true` if message has any reactions pub fn has_reactions(&self) -> bool { !self.0.reactions.is_empty() } From 394e7a264f47d3a82b17da417d7478aacc4b0687 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 01:37:38 +0200 Subject: [PATCH 25/28] best practice naming --- src/backend/nc_request.rs | 2 +- src/backend/nc_room.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/nc_request.rs b/src/backend/nc_request.rs index c23dc2b..b2f8da6 100644 --- a/src/backend/nc_request.rs +++ b/src/backend/nc_request.rs @@ -32,7 +32,7 @@ pub struct NCReqMeta { #[derive(Serialize, Deserialize, Debug, Default, Clone)] pub struct NCReqDataMessageParameter { #[serde(rename = "type")] - paramtype: String, + param_type: String, id: String, name: String, } diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index edc5cc0..9bea148 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -191,17 +191,17 @@ impl NCRoom { pub async fn update_if_id_is_newer( &mut self, - messageid: i32, + message_id: i32, data_option: Option<&NCReqDataRoom>, ) -> Result<(), Box> { if let Some(last_internal_id) = self.get_last_room_level_message_id() { - match messageid.cmp(&last_internal_id) { + match message_id.cmp(&last_internal_id) { Ordering::Greater => { log::info!( "New Messages for '{}' was {} now {}", self.to_string(), last_internal_id, - messageid + message_id ); self.update(data_option).await?; } @@ -210,7 +210,7 @@ impl NCRoom { "Message Id was older than message stored '{}'! Stored {} Upstream {}", self.to_string(), last_internal_id, - messageid + message_id ); } Ordering::Equal => (), From fd677a12a309c0bf3913c9e9ee8c553056126418 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 01:46:46 +0200 Subject: [PATCH 26/28] qualify lonely std usages --- src/backend/nc_request.rs | 14 ++++++++------ src/backend/nc_room.rs | 33 +++++++++++++++------------------ src/backend/nc_talk.rs | 17 ++++++----------- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/backend/nc_request.rs b/src/backend/nc_request.rs index b2f8da6..9769b0a 100644 --- a/src/backend/nc_request.rs +++ b/src/backend/nc_request.rs @@ -2,6 +2,7 @@ #![allow(unused_variables)] #![allow(dead_code)] +use crate::config; use base64::{prelude::BASE64_STANDARD, write::EncoderWriter}; use jzon; use reqwest::{ @@ -9,17 +10,14 @@ use reqwest::{ Client, Response, Url, }; use serde::{Deserialize, Deserializer, Serialize}; -use std::path::PathBuf; -use std::{collections::HashMap, error::Error, fs::File, io::Write}; - -use crate::config; +use std::{collections::HashMap, error::Error}; #[derive(Debug, Clone)] pub struct NCRequest { base_url: String, client: Client, base_headers: HeaderMap, - json_dump_path: Option, + json_dump_path: Option, } #[derive(Serialize, Deserialize, Debug, Default)] @@ -247,6 +245,8 @@ pub struct NCReqOCS { impl NCRequest { pub fn new() -> Result> { + use std::io::Write; + let config = &config::get(); let general = &config.data.general; @@ -542,12 +542,14 @@ impl NCRequest { } fn dump_json_to_log(&self, url: &str, text: &str) -> Result<(), Box> { + use std::io::Write; + if let Some(path) = &self.json_dump_path { let name: String = url .chars() .map(|ch| if ch == '/' { '_' } else { ch }) .collect(); - let mut file = File::create(name)?; + let mut file = std::fs::File::create(name)?; let pretty_text = jzon::stringify_pretty(jzon::parse(text)?, 2); file.write_all(pretty_text.as_bytes())?; } diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index 9bea148..af1024a 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -6,13 +6,6 @@ use super::{ use log; use num_derive::FromPrimitive; use num_traits::{AsPrimitive, FromPrimitive}; -use std::{ - cmp::Ordering, - error::Error, - fs::{read_to_string, File}, - io::prelude::*, - path::PathBuf, -}; #[derive(Debug, FromPrimitive, PartialEq)] pub enum NCRoomTypes { @@ -30,7 +23,7 @@ pub struct NCRoom { notifier: NCNotify, pub messages: Vec, room_data: NCReqDataRoom, - path_to_log: PathBuf, + path_to_log: std::path::PathBuf, pub room_type: NCRoomTypes, participants: Vec, } @@ -40,7 +33,7 @@ impl NCRoom { requester: NCRequest, token: String, messages: &mut Vec, - ) -> Result<(), Box> { + ) -> Result<(), Box> { let response = requester .fetch_chat_initial(token.clone().as_str(), 200) .await?; @@ -54,7 +47,7 @@ impl NCRoom { room_data: NCReqDataRoom, requester: NCRequest, notifier: NCNotify, - path_to_log: PathBuf, + path_to_log: std::path::PathBuf, ) -> Option { let mut tmp_path_buf = path_to_log.clone(); tmp_path_buf.push(room_data.token.as_str()); @@ -64,7 +57,7 @@ impl NCRoom { if path.exists() { if let Ok(data) = serde_json::from_str::>( - read_to_string(path).unwrap().as_str(), + std::fs::read_to_string(path).unwrap().as_str(), ) { messages.extend(data.into_iter().map(Into::into)); } else { @@ -100,7 +93,7 @@ impl NCRoom { }) } - pub async fn send(&self, message: String) -> Result> { + pub async fn send(&self, message: String) -> Result> { log::debug!("Send Message {}", &message); let response = self .requester @@ -115,7 +108,7 @@ impl NCRoom { pub async fn update( &mut self, data_option: Option<&NCReqDataRoom>, - ) -> Result<(), Box> { + ) -> Result<(), Box> { if let Some(data) = data_option { self.room_data = data.clone(); } @@ -161,7 +154,7 @@ impl NCRoom { .map(|message| message.get_id()) } - pub async fn mark_as_read(&self) -> Result<(), Box> { + pub async fn mark_as_read(&self) -> Result<(), Box> { if !self.messages.is_empty() { self.requester .mark_chat_read( @@ -193,7 +186,9 @@ impl NCRoom { &mut self, message_id: i32, data_option: Option<&NCReqDataRoom>, - ) -> Result<(), Box> { + ) -> Result<(), Box> { + use std::cmp::Ordering; + if let Some(last_internal_id) = self.get_last_room_level_message_id() { match message_id.cmp(&last_internal_id) { Ordering::Greater => { @@ -228,10 +223,12 @@ impl NCRoom { } pub fn write_to_log(&mut self) -> Result<(), std::io::Error> { + use std::io::Write; + let data: Vec<_> = self.messages.iter().map(NCMessage::data).collect(); let path = self.path_to_log.as_path(); // Open a file in write-only mode, returns `io::Result` - let mut file = match File::create(path) { + let mut file = match std::fs::File::create(path) { Err(why) => { log::warn!( "Couldn't create log file {} for {}: {}", @@ -266,13 +263,13 @@ impl NCRoom { } impl Ord for NCRoom { - fn cmp(&self, other: &Self) -> Ordering { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.to_string().cmp(other) } } impl PartialOrd for NCRoom { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } diff --git a/src/backend/nc_talk.rs b/src/backend/nc_talk.rs index c2e4886..b41104c 100644 --- a/src/backend/nc_talk.rs +++ b/src/backend/nc_talk.rs @@ -1,5 +1,3 @@ -use itertools::Itertools; - use crate::{ backend::{ nc_notify::NCNotify, @@ -9,13 +7,8 @@ use crate::{ config::{self}, }; use core::panic; -use std::{ - collections::HashMap, - error::Error, - fs::{read_to_string, File}, - io::prelude::*, - path::PathBuf, -}; +use itertools::Itertools; +use std::{collections::HashMap, error::Error, path::PathBuf}; #[derive(Debug)] pub struct NCTalk { @@ -84,7 +77,7 @@ impl NCTalk { if path.exists() { if let Ok(mut data) = serde_json::from_str::>( - read_to_string(path).unwrap().as_str(), + std::fs::read_to_string(path).unwrap().as_str(), ) { let mut handles = HashMap::new(); for (token, room) in &mut data { @@ -177,6 +170,8 @@ impl NCTalk { } pub fn write_to_log(&mut self) -> Result<(), std::io::Error> { + use std::io::Write; + let mut data = HashMap::::new(); let mut tmp_path_buf = self.chat_data_path.clone(); tmp_path_buf.push("Talk.json"); @@ -186,7 +181,7 @@ impl NCTalk { room.write_to_log()?; } // Open a file in write-only mode, returns `io::Result` - let mut file = match File::create(path) { + let mut file = match std::fs::File::create(path) { Err(why) => { log::warn!( "couldn't create top level log file {}: {}", From ca75e55d94e252c7a53eeacba0ee5a4d8a1dae9a Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 01:52:59 +0200 Subject: [PATCH 27/28] fix member initialization order --- src/backend/nc_room.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index af1024a..611f709 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -76,7 +76,6 @@ impl NCRoom { .ok(); } - let type_num = room_data.roomtype; let participants = requester .fetch_participants(&room_data.token) .await @@ -85,11 +84,11 @@ impl NCRoom { Some(NCRoom { requester, notifier, - room_data, messages, path_to_log: tmp_path_buf, - room_type: FromPrimitive::from_i32(type_num).unwrap(), + room_type: FromPrimitive::from_i32(room_data.roomtype).unwrap(), participants, + room_data, }) } From 103163cfa847c3d5e9fdb7ea4da6f3c1bdb8a266 Mon Sep 17 00:00:00 2001 From: Patrick Hoffmann Date: Thu, 29 Aug 2024 02:04:34 +0200 Subject: [PATCH 28/28] remove some clone() --- src/backend/nc_room.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/backend/nc_room.rs b/src/backend/nc_room.rs index 611f709..a54bd04 100644 --- a/src/backend/nc_room.rs +++ b/src/backend/nc_room.rs @@ -30,13 +30,11 @@ pub struct NCRoom { impl NCRoom { async fn fetch_messages( - requester: NCRequest, - token: String, + requester: &NCRequest, + token: &str, messages: &mut Vec, ) -> Result<(), Box> { - let response = requester - .fetch_chat_initial(token.clone().as_str(), 200) - .await?; + let response = requester.fetch_chat_initial(token, 200).await?; for message in response { messages.push(message.into()); } @@ -65,13 +63,13 @@ impl NCRoom { "Failed to parse json for {}, falling back to fetching", room_data.displayName ); - NCRoom::fetch_messages(requester.clone(), room_data.token.clone(), &mut messages) + NCRoom::fetch_messages(&requester, &room_data.token, &mut messages) .await .ok(); } } else { log::debug!("No Log File found for room {}", room_data.displayName); - NCRoom::fetch_messages(requester.clone(), room_data.token.clone(), &mut messages) + NCRoom::fetch_messages(&requester, &room_data.token, &mut messages) .await .ok(); } @@ -114,7 +112,7 @@ impl NCRoom { let response = self .requester .fetch_chat_update( - self.room_data.token.clone().as_str(), + self.room_data.token.as_str(), 200, self.messages.last().unwrap().get_id(), )