diff --git a/Cargo.lock b/Cargo.lock index 9ca81ce..782665d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,7 +213,7 @@ dependencies = [ "log", "num", "owning_ref", - "syn 1.0.67", + "syn 1.0.68", "unicode-segmentation", "unicode-width", "wasmer_enumset", @@ -223,11 +223,11 @@ dependencies = [ [[package]] name = "cursive_tree_view" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd59affc6d600a69df27972fb5fe7f38a743aeb0710299e3324022c7d80717a0" +source = "git+https://github.com/FliegendeWurst/cursive_tree_view.git?branch=master#f3a0470f229a5ab57da600cf552b916ad33c6390" dependencies = [ "cursive_core", "debug_stub_derive", + "unicode-segmentation", ] [[package]] @@ -251,7 +251,7 @@ dependencies = [ "proc-macro2", "quote 1.0.9", "strsim", - "syn 1.0.67", + "syn 1.0.68", ] [[package]] @@ -262,7 +262,7 @@ checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" dependencies = [ "darling_core", "quote 1.0.9", - "syn 1.0.67", + "syn 1.0.68", ] [[package]] @@ -335,7 +335,7 @@ checksum = "e5c450cf304c9e18d45db562025a14fb1ca0f5c769b6f609309f81d4c31de455" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.67", + "syn 1.0.68", ] [[package]] @@ -525,8 +525,8 @@ checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714" [[package]] name = "libsqlite3-sys" -version = "0.21.0" -source = "git+https://github.com/rusqlite/rusqlite?branch=master#ed3bfbdf9d9e577e8d4cff937b053a0e429a4cd7" +version = "0.22.0" +source = "git+https://github.com/rusqlite/rusqlite?branch=master#ddf69f749a67fdb673837ebb3c881a522fd7f638" dependencies = [ "cc", "pkg-config", @@ -595,9 +595,9 @@ dependencies = [ [[package]] name = "mime2ext" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88947611258697e12f8602a44003b0885ca5fe30f27132d63c8f47fe98f2f2e" +checksum = "d8b337a0b7c1d5d8d3c08096823831a5d7a3f6aadea1150b7fe622c38c14e283" dependencies = [ "serde", "serde_json", @@ -751,9 +751,9 @@ checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid 0.2.1", ] @@ -851,8 +851,8 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.24.2" -source = "git+https://github.com/rusqlite/rusqlite?branch=master#ed3bfbdf9d9e577e8d4cff937b053a0e429a4cd7" +version = "0.25.0" +source = "git+https://github.com/rusqlite/rusqlite?branch=master#ddf69f749a67fdb673837ebb3c881a522fd7f638" dependencies = [ "bitflags", "fallible-iterator", @@ -995,7 +995,7 @@ checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.67", + "syn 1.0.68", ] [[package]] @@ -1081,9 +1081,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" +checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87" dependencies = [ "proc-macro2", "quote 1.0.9", @@ -1206,7 +1206,7 @@ dependencies = [ "log", "proc-macro2", "quote 1.0.9", - "syn 1.0.67", + "syn 1.0.68", "wasm-bindgen-shared", ] @@ -1228,7 +1228,7 @@ checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ "proc-macro2", "quote 1.0.9", - "syn 1.0.67", + "syn 1.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1258,7 +1258,7 @@ dependencies = [ "darling", "proc-macro2", "quote 1.0.9", - "syn 1.0.67", + "syn 1.0.68", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7ae0f79..074c76d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,4 +25,7 @@ subprocess = "0.2.6" mime2ext = "0.1.2" petgraph = "0.5.1" cursive = { version = "0.16.3", default-features = false, features = ["termion-backend"] } -cursive_tree_view = "0.7.0" +cursive_tree_view = { git = "https://github.com/FliegendeWurst/cursive_tree_view.git", branch = "master" } + +[profile.release] +overflow-checks = true diff --git a/src/bin/browse.rs b/src/bin/browse.rs index b210186..6153a3d 100644 --- a/src/bin/browse.rs +++ b/src/bin/browse.rs @@ -6,7 +6,7 @@ use cursive::{Cursive, CursiveExt}; use cursive::traits::Identifiable; use cursive::view::{Scrollable, SizeConstraint}; use cursive::views::{LinearLayout, ResizedView, TextView}; -use cursive_tree_view::{Placement, TreeView}; +use cursive_tree_view::{Placement, TreeEntry, TreeView}; use inboxid::*; use io::Write; use itertools::Itertools; @@ -25,8 +25,8 @@ fn main() -> Result<()> { } }); match result { - Ok(res) => res, - Err(_) => { + Ok(res) => res, + Err(_) => { if let Err(e) = io::stderr().lock().write_all(&sink.lock().unwrap()) { println!("{:?}", e); } @@ -62,7 +62,7 @@ fn show_listing(mailbox: &str) -> Result<()> { } else { flags_display.push('*'); } - rows.push(IntoIter::new([(mails.len() - i).to_string(), flags_display, mail.from.clone(), mail.subject.clone(), mail.date_iso.clone()])); + rows.push(IntoIter::new([(mails.len() - i).to_string(), flags_display, mail.from(), mail.subject.clone(), mail.date_iso.clone()])); } let mut mails_by_id = HashMap::new(); @@ -251,15 +251,17 @@ struct MailPart { } impl Display for MailPart { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.part.ctype.mimetype) - } + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.part.ctype.mimetype) + } } impl From<&'static ParsedMail<'static>> for MailPart { - fn from(part: &'static ParsedMail<'static>) -> Self { - Self { + fn from(part: &'static ParsedMail<'static>) -> Self { + Self { part } - } + } } + +impl TreeEntry for MailPart {} diff --git a/src/bin/list.rs b/src/bin/list.rs index 40606da..dc1167a 100644 --- a/src/bin/list.rs +++ b/src/bin/list.rs @@ -40,7 +40,7 @@ fn show_listing(mailbox: &str) -> Result<()> { } else { flags_display.push('*'); } - rows.push(IntoIter::new([(mails.len() - i).to_string(), flags_display, mail.from.clone(), mail.subject.clone(), mail.date_iso.clone()])); + rows.push(IntoIter::new([(mails.len() - i).to_string(), flags_display, mail.from(), mail.subject.clone(), mail.date_iso.clone()])); } let mut ascii_table = AsciiTable::default(); diff --git a/src/bin/new.rs b/src/bin/new.rs index db53dfb..8694e68 100644 --- a/src/bin/new.rs +++ b/src/bin/new.rs @@ -26,7 +26,7 @@ fn show_listing(mailbox: &str) -> Result<()> { let mut rows = Vec::new(); for mail in &mails { - rows.push(IntoIter::new([mail.from.clone(), mail.subject.clone(), mail.date_iso.clone()])); + rows.push(IntoIter::new([mail.from(), mail.subject.clone(), mail.date_iso.clone()])); } let mut ascii_table = AsciiTable::default(); diff --git a/src/lib.rs b/src/lib.rs index 3d35cdf..e313ba7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,12 @@ -use std::{borrow::Cow, convert::{TryFrom, TryInto}, env, fmt::{Debug, Display}, fs, hash::Hash, io, net::TcpStream, ops::Deref}; +use std::{borrow::Cow, cmp, convert::{TryFrom, TryInto}, env, fmt::{Debug, Display}, fs, hash::Hash, io, net::TcpStream, ops::Deref}; use anyhow::Context; use chrono::{DateTime, Local, NaiveDateTime, TimeZone}; +use cursive::{theme::Style, utils::span::{IndexedCow, IndexedSpan, SpannedString}}; +use cursive_tree_view::TreeEntry; use imap::{Session, types::Flag}; use maildir::{MailEntry, Maildir}; -use mailparse::{MailHeaderMap, ParsedMail, dateparse}; +use mailparse::{MailHeaderMap, ParsedMail, SingleInfo, addrparse, dateparse}; use petgraph::{Graph, graph::NodeIndex}; use rusqlite::{Connection, params}; use rustls_connector::{RustlsConnector, rustls::{ClientSession, StreamOwned}}; @@ -96,7 +98,7 @@ pub struct EasyMail<'a> { mail: Option>, pub id: MaildirID, pub flags: String, - pub from: String, + from: SingleInfo, pub subject: String, pub date: DateTime, pub date_iso: String, @@ -108,7 +110,10 @@ impl EasyMail<'_> { mail: None, id: MaildirID::new(0, 0), flags: "S".to_owned(), - from: String::new(), + from: SingleInfo { + display_name: None, + addr: String::new() + }, subject, date: Local.from_utc_datetime(&NaiveDateTime::from_timestamp(0, 0)), date_iso: "????-??-??".to_owned() @@ -119,6 +124,10 @@ impl EasyMail<'_> { self.mail.is_none() } + pub fn from(&self) -> String { + self.from.display_name.as_deref().unwrap_or_default().to_owned() + } + pub fn get_header(&self, header: &str) -> String { self.get_headers().get_all_values(header).join(" ") } @@ -151,7 +160,8 @@ impl Eq for EasyMail<'_> {} impl Hash for EasyMail<'_> { fn hash(&self, state: &mut H) { self.id.hash(state); - self.from.hash(state); + self.from.display_name.hash(state); + self.from.addr.hash(state); self.subject.hash(state); } } @@ -164,6 +174,76 @@ impl<'a> Deref for EasyMail<'a> { } } +impl TreeEntry for &EasyMail<'_> { + fn display(&self, width: usize) -> SpannedString