From eb4399571884318243e067ad45f952374c1eab68 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Thu, 22 Feb 2024 10:54:25 +0200 Subject: [PATCH] feat: add `Selected` enum --- src/app/command.rs | 62 ++++++++++++++-------------------------------- src/app/mod.rs | 27 +++++++++++--------- src/app/types.rs | 36 +++++++++++++++++++++++++++ src/ui/table.rs | 2 +- 4 files changed, 71 insertions(+), 56 deletions(-) create mode 100644 src/app/types.rs diff --git a/src/app/command.rs b/src/app/command.rs index 9d7c44d..a248eb3 100644 --- a/src/app/command.rs +++ b/src/app/command.rs @@ -1,43 +1,26 @@ -use std::path::Path; +use std::{collections::HashSet, path::Path, vec}; -use tracing::debug; use transmission_rpc::types::{Id, Torrent, TorrentAction, TorrentStatus}; -use super::Torrents; +use super::{types::Selected, Torrents}; impl Torrents { - pub async fn toggle(&mut self, ids: &Vec) { - debug!("ID list - {:?}", ids); - - let api_ids: Vec<_> = self - .torrents - .iter() - .filter_map(|torrent| { - if let Some(id) = torrent.id { - if ids.contains(&id) { - return torrent.id(); - } - } - return None; - }) - .collect(); - - debug!("API ID list - {:?}", api_ids); - - for torrent in &self.torrents { + pub async fn toggle(&mut self, ids: Selected) { + let ids: HashSet<_> = ids.into(); + let torrents = self.torrents.iter().filter(|torrent| { if let Some(id) = torrent.id { - if ids.contains(&id) { - let action = match torrent.status { - Some(TorrentStatus::Stopped) => TorrentAction::Start, - _ => TorrentAction::Stop, - }; - if !api_ids.is_empty() { - if let Err(err) = self.client.torrent_action(action, api_ids.clone()).await - { - eprintln!("Error toggling torrent: {}", err); - } - } - } + return ids.contains(&id); + } + false + }); + + for torrent in torrents { + let action = match torrent.status { + Some(TorrentStatus::Stopped) => TorrentAction::Start, + _ => TorrentAction::Stop, + }; + if let Some(id) = torrent.id() { + self.client.torrent_action(action, vec![id]).await.unwrap(); } } } @@ -90,16 +73,9 @@ impl Torrents { Ok(()) } - pub async fn delete(&mut self, ids: &Vec, delete_local_data: bool) { - let api_ids = self - .torrents - .iter() - .filter(|torrent| ids.contains(&torrent.id.unwrap())) - .map(|torrent| torrent.id().unwrap()) - .collect(); - + pub async fn delete(&mut self, ids: Selected, delete_local_data: bool) { self.client - .torrent_remove(api_ids, delete_local_data) + .torrent_remove(ids.into(), delete_local_data) .await .unwrap(); } diff --git a/src/app/mod.rs b/src/app/mod.rs index 27065b7..6fb8d57 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -5,7 +5,9 @@ pub mod utils; use ratatui::widgets::TableState; pub mod action; mod command; +pub mod types; +use self::types::Selected; pub use self::{tab::Tab, torrent::Torrents}; /// Main Application. @@ -119,28 +121,29 @@ impl<'a> App<'a> { } pub async fn toggle_torrents(&mut self) { - let ids = &self.selected(false); + let ids = self.selected(false); self.torrents.toggle(ids).await; self.close_popup(); } pub async fn delete(&mut self, delete_local_data: bool) { - let ids = &self.selected(false); + let ids = self.selected(false); self.torrents.delete(ids, delete_local_data).await; self.close_popup(); } pub fn select(&mut self) { - let current_id = *self.selected(true).first().unwrap(); - if self.torrents.selected.contains(¤t_id) { - self.torrents.selected.remove(¤t_id); - } else { - self.torrents.selected.insert(current_id); + if let Selected::Current(current_id) = self.selected(true) { + if self.torrents.selected.contains(¤t_id) { + self.torrents.selected.remove(¤t_id); + } else { + self.torrents.selected.insert(current_id); + } } self.next(); } - fn selected(&self, highlighted: bool) -> Vec { + fn selected(&self, highlighted: bool) -> Selected { let torrents = &self.torrents.torrents; if self.torrents.selected.is_empty() || highlighted { let torrent_id = || { @@ -149,19 +152,19 @@ impl<'a> App<'a> { torrent.id }; if let Some(id) = torrent_id() { - return vec![id]; + return Selected::Current(id); } } - let selected_torrents: Vec<_> = torrents + let selected_torrents = torrents .iter() .filter_map(|torrent| { let id = torrent.id; if self.torrents.selected.contains(&id?) { return id; } - return None; + None }) .collect(); - selected_torrents + Selected::List(selected_torrents) } } diff --git a/src/app/types.rs b/src/app/types.rs new file mode 100644 index 0000000..ef7f659 --- /dev/null +++ b/src/app/types.rs @@ -0,0 +1,36 @@ +use std::collections::HashSet; + +use transmission_rpc::types::Id; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Selected { + Current(i64), + List(HashSet), +} + +impl Into> for Selected { + fn into(self) -> HashSet { + match self { + Selected::Current(id) => vec![id].into_iter().collect(), + Selected::List(ids) => ids, + } + } +} + +impl Into> for Selected { + fn into(self) -> Vec { + match self { + Selected::Current(id) => vec![id], + Selected::List(ids) => ids.into_iter().collect(), + } + } +} + +impl Into> for Selected { + fn into(self) -> Vec { + match self { + Selected::Current(id) => vec![Id::Id(id)], + Selected::List(ids) => ids.into_iter().map(Id::Id).collect(), + } + } +} diff --git a/src/ui/table.rs b/src/ui/table.rs index f88e2aa..065ea2a 100644 --- a/src/ui/table.rs +++ b/src/ui/table.rs @@ -24,7 +24,7 @@ pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> { return field.value(torrent.clone()).set_style(highlight_style); } } - return field.value(torrent.clone()).into(); + field.value(torrent.clone()).into() }) .collect::>(), )