From d9defdec45954d59b009ea7d55d6c9d1b0d7acbf Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Sat, 10 May 2025 14:11:37 -0300 Subject: [PATCH] refactor: move list mode handling to modes/list.rs --- src/main.rs | 169 -------------------------------------------- src/modes/list.rs | 25 ++++--- src/modes/status.rs | 2 +- 3 files changed, 17 insertions(+), 179 deletions(-) diff --git a/src/main.rs b/src/main.rs index d66a4cf..ccf6b05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ use nix::fcntl::FdFlag; use nix::unistd::{close, pipe}; use nix::Error as NixError; -use std::collections::HashMap; use std::io::Read; use std::os::fd::FromRawFd; use std::path::PathBuf; @@ -13,20 +12,15 @@ use clap::*; use log::*; use rusqlite::Connection; mod modes; -use crate::modes::common::*; extern crate directories; use directories::ProjectDirs; extern crate prettytable; -use prettytable::color; use prettytable::format; use prettytable::format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR; use prettytable::format::{Alignment, TableFormat}; -use prettytable::row; -use prettytable::{Attr, Cell, Row, Table}; -use chrono::prelude::*; use std::io::BufWriter; use std::str::FromStr; @@ -593,166 +587,3 @@ fn mode_diff( Ok(()) } - -fn mode_list( - cmd: &mut Command, - args: Args, - ids: &mut Vec, - tags: &Vec, - conn: &mut Connection, - data_path: PathBuf, -) -> Result<()> { - if !ids.is_empty() { - cmd.error( - ErrorKind::InvalidValue, - "ID given, you can only supply tags when using --list", - ) - .exit(); - } - - let mut meta: HashMap = HashMap::new(); - for item in args.item.meta.iter() { - let item = item.clone(); - meta.insert(item.key, item.value); - } - - let items = match tags.is_empty() && meta.is_empty() { - true => db::get_items(conn)?, - false => db::get_items_matching(conn, tags, &meta)?, - }; - - debug!("MAIN: Items: {:?}", items); - - let mut tags_by_item: HashMap> = HashMap::new(); - let mut meta_by_item: HashMap> = HashMap::new(); - - for item in items.iter() { - let item_id = item.id.unwrap(); - - let item_tags: Vec = db::get_item_tags(conn, item)? - .into_iter() - .map(|x| x.name) - .collect(); - tags_by_item.insert(item_id, item_tags); - - let mut item_meta: HashMap = HashMap::new(); - - for meta in db::get_item_meta(conn, item)? { - item_meta.insert(meta.name.clone(), meta.value); - } - meta_by_item.insert(item_id, item_meta); - } - - let mut table = Table::new(); - table.set_format(*format::consts::FORMAT_CLEAN); - - let list_format = args.options.list_format.split(","); - - let mut title_row = row!(); - - for column in list_format.clone() { - let mut column_format = column.split(":").into_iter(); - let column_name = column_format.next().expect("Unable to parse column name"); - let column_type = ColumnType::from_str(column_name) - .expect(format!("Unknown column {:?}", column_name).as_str()); - - if column_type == ColumnType::Meta { - let meta_name = column_format - .next() - .expect("Unable to parse metadata name for meta column"); - title_row.add_cell(Cell::new(meta_name).with_style(Attr::Bold)); - } else { - title_row.add_cell(Cell::new(&column_type.to_string()).with_style(Attr::Bold)); - } - } - - table.set_titles(title_row); - - for item in items { - let item_id = item.id.unwrap(); - let tags = tags_by_item.get(&item_id).unwrap(); - let meta = meta_by_item.get(&item_id).unwrap(); - let mut item_path = data_path.clone(); - item_path.push(item.id.unwrap().to_string()); - - let mut table_row = Row::new(vec![]); - - for column in list_format.clone() { - let mut column_format = column.split(":").into_iter(); - let column_name = column_format.next().expect("Unable to parse column name"); - let column_type = ColumnType::from_str(column_name) - .expect(format!("Unknown column {:?}", column_name).as_str()); - let mut meta_name: Option<&str> = None; - - if column_type == ColumnType::Meta { - meta_name = column_format.next(); - } - - let column_width: usize = match column_format.next() { - Some(len) => len.parse().unwrap_or(0), - None => 0, - }; - - let cell = match column_type { - ColumnType::Id => Cell::new_align( - &string_column(item.id.unwrap_or(0).to_string(), column_width), - Alignment::RIGHT, - ), - ColumnType::Time => Cell::new(&string_column( - item.ts.with_timezone(&Local).format("%F %T").to_string(), - column_width, - )), - ColumnType::Size => match item.size { - Some(size) => Cell::new_align( - &size_column(size as u64, args.options.human_readable, column_width), - Alignment::RIGHT, - ), - None => match item_path.metadata() { - Ok(_) => Cell::new_align("Unknown", Alignment::RIGHT) - .with_style(Attr::ForegroundColor(color::YELLOW)) - .with_style(Attr::Bold), - Err(_) => Cell::new_align("Missing", Alignment::RIGHT) - .with_style(Attr::ForegroundColor(color::RED)) - .with_style(Attr::Bold), - }, - }, - ColumnType::Compression => { - Cell::new(&string_column(item.compression.to_string(), column_width)) - } - ColumnType::FileSize => match item_path.metadata() { - Ok(metadata) => Cell::new_align( - &size_column( - metadata.len() as u64, - args.options.human_readable, - column_width, - ), - Alignment::RIGHT, - ), - Err(_) => Cell::new_align("Missing", Alignment::RIGHT) - .with_style(Attr::ForegroundColor(color::RED)) - .with_style(Attr::Bold), - }, - ColumnType::FilePath => Cell::new(&string_column( - item_path.clone().into_os_string().into_string().unwrap(), - column_width, - )), - ColumnType::Tags => Cell::new(&string_column(tags.join(" "), column_width)), - ColumnType::Meta => match meta_name { - Some(meta_name) => match meta.get(meta_name) { - Some(meta_value) => { - Cell::new(&string_column(meta_value.to_string(), column_width)) - } - None => Cell::new(""), - }, - None => Cell::new(""), - }, - }; - table_row.add_cell(cell); - } - table.add_row(table_row); - } - - table.printstd(); - - Ok(()) -} diff --git a/src/modes/list.rs b/src/modes/list.rs index 8e17efd..32132cf 100644 --- a/src/modes/list.rs +++ b/src/modes/list.rs @@ -3,11 +3,11 @@ use crate::Alignment; use crate::db::{get_items, get_items_matching}; use crate::modes::common::ColumnType; use crate::modes::common::{size_column, string_column}; +use anyhow::anyhow; +use log::debug; use prettytable::color; use prettytable::row; use prettytable::{Attr, Cell, Row, Table}; -use log::debug; -use anyhow::anyhow; pub fn mode_list( cmd: &mut clap::Command, @@ -38,8 +38,12 @@ pub fn mode_list( debug!("MAIN: Items: {:?}", items); - let mut tags_by_item: std::collections::HashMap> = std::collections::HashMap::new(); - let mut meta_by_item: std::collections::HashMap> = std::collections::HashMap::new(); + let mut tags_by_item: std::collections::HashMap> = + std::collections::HashMap::new(); + let mut meta_by_item: std::collections::HashMap< + i64, + std::collections::HashMap, + > = std::collections::HashMap::new(); for item in items.iter() { let item_id = item.id.unwrap(); @@ -50,7 +54,8 @@ pub fn mode_list( .collect(); tags_by_item.insert(item_id, item_tags); - let mut item_meta: std::collections::HashMap = std::collections::HashMap::new(); + let mut item_meta: std::collections::HashMap = + std::collections::HashMap::new(); for meta in crate::db::get_item_meta(conn, item)? { item_meta.insert(meta.name.clone(), meta.value); @@ -68,9 +73,8 @@ pub fn mode_list( for column in list_format.clone() { let mut column_format = column.split(":").into_iter(); let column_name = column_format.next().expect("Unable to parse column name"); - let column_type = ColumnType::from_str(column_name).map_err(|_| { - anyhow!("Unknown column {:?}", column_name) - })?; + let column_type = ColumnType::from_str(column_name) + .map_err(|_| anyhow!("Unknown column {:?}", column_name))?; if column_type == ColumnType::Meta { let meta_name = column_format @@ -115,7 +119,10 @@ pub fn mode_list( Alignment::RIGHT, ), ColumnType::Time => Cell::new(&string_column( - item.ts.with_timezone(&chrono::Local).format("%F %T").to_string(), + item.ts + .with_timezone(&chrono::Local) + .format("%F %T") + .to_string(), column_width, )), ColumnType::Size => match item.size { diff --git a/src/modes/status.rs b/src/modes/status.rs index a1294d2..f4b040f 100644 --- a/src/modes/status.rs +++ b/src/modes/status.rs @@ -5,9 +5,9 @@ use std::path::PathBuf; use strum::IntoEnumIterator; use crate::compression::default_type; +use crate::compression::program::CompressionEngineProgram; use crate::compression::CompressionType; use crate::compression::COMPRESSION_PROGRAMS; -use crate::compression::program::CompressionEngineProgram; use std::str::FromStr; use crate::FORMAT_BOX_CHARS_NO_BORDER_LINE_SEPARATOR;