mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-25 04:20:22 +00:00
fix flags case sensitivity
This commit is contained in:
parent
0ab652b4b6
commit
3631ca714b
13 changed files with 194 additions and 17 deletions
|
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- Fixed config deserialization issue with `email-hooks` and
|
||||
`email-reading-format`.
|
||||
- Fixed flags case sensitivity.
|
||||
|
||||
## [0.7.1] - 2023-02-14
|
||||
|
||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -775,6 +775,7 @@ version = "0.7.1"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"atty",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_mangen",
|
||||
|
@ -803,7 +804,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "himalaya-lib"
|
||||
version = "0.6.0"
|
||||
source = "git+https://git.sr.ht/~soywod/himalaya-lib?branch=develop#8c538689c9d3098f8e69493791ccbbe52eb9af58"
|
||||
source = "git+https://git.sr.ht/~soywod/himalaya-lib?branch=develop#26d3b9e74c978f6dc94689bff809d48fe5ba4c85"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"chrono",
|
||||
|
@ -827,7 +828,6 @@ dependencies = [
|
|||
"regex",
|
||||
"rfc2047-decoder",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"shellexpand",
|
||||
"thiserror",
|
||||
"tree_magic",
|
||||
|
|
|
@ -27,6 +27,7 @@ tempfile = "3.3"
|
|||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
atty = "0.2"
|
||||
chrono = "0.4.23"
|
||||
clap = "4.0"
|
||||
clap_complete = "4.0"
|
||||
clap_mangen = "0.2"
|
||||
|
|
|
@ -14,6 +14,7 @@ use uuid::Uuid;
|
|||
use crate::{
|
||||
printer::{PrintTableOpts, Printer},
|
||||
ui::editor,
|
||||
Envelopes,
|
||||
};
|
||||
|
||||
pub fn attachments<P: Printer, B: Backend + ?Sized>(
|
||||
|
@ -132,10 +133,10 @@ pub fn list<P: Printer, B: Backend + ?Sized>(
|
|||
let folder = config.folder_alias(folder)?;
|
||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||
debug!("page size: {}", page_size);
|
||||
let msgs = backend.list_envelopes(&folder, page_size, page)?;
|
||||
trace!("envelopes: {:?}", msgs);
|
||||
let envelopes: Envelopes = backend.list_envelopes(&folder, page_size, page)?.into();
|
||||
trace!("envelopes: {:?}", envelopes);
|
||||
printer.print_table(
|
||||
Box::new(msgs),
|
||||
Box::new(envelopes),
|
||||
PrintTableOpts {
|
||||
format: &config.email_reading_format,
|
||||
max_width,
|
||||
|
@ -291,7 +292,9 @@ pub fn search<P: Printer, B: Backend + ?Sized>(
|
|||
) -> Result<()> {
|
||||
let folder = config.folder_alias(folder)?;
|
||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||
let envelopes = backend.search_envelopes(&folder, &query, "", page_size, page)?;
|
||||
let envelopes: Envelopes = backend
|
||||
.search_envelopes(&folder, &query, "", page_size, page)?
|
||||
.into();
|
||||
let opts = PrintTableOpts {
|
||||
format: &config.email_reading_format,
|
||||
max_width,
|
||||
|
@ -313,7 +316,9 @@ pub fn sort<P: Printer, B: Backend + ?Sized>(
|
|||
) -> Result<()> {
|
||||
let folder = config.folder_alias(folder)?;
|
||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||
let envelopes = backend.search_envelopes(&folder, &query, &sort, page_size, page)?;
|
||||
let envelopes: Envelopes = backend
|
||||
.search_envelopes(&folder, &query, &sort, page_size, page)?
|
||||
.into();
|
||||
let opts = PrintTableOpts {
|
||||
format: &config.email_reading_format,
|
||||
max_width,
|
||||
|
|
|
@ -1,6 +1,45 @@
|
|||
use himalaya_lib::{Envelope, Flag};
|
||||
use chrono::{DateTime, Local};
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::ui::{Cell, Row, Table};
|
||||
use crate::{
|
||||
ui::{Cell, Row, Table},
|
||||
Flag, Flags,
|
||||
};
|
||||
|
||||
fn date<S: Serializer>(date: &DateTime<Local>, s: S) -> Result<S::Ok, S::Error> {
|
||||
s.serialize_str(&date.to_rfc3339())
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
pub struct Mailbox {
|
||||
pub name: Option<String>,
|
||||
pub addr: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
pub struct Envelope {
|
||||
pub id: String,
|
||||
pub flags: Flags,
|
||||
pub subject: String,
|
||||
pub from: Mailbox,
|
||||
#[serde(serialize_with = "date")]
|
||||
pub date: DateTime<Local>,
|
||||
}
|
||||
|
||||
impl From<&himalaya_lib::Envelope> for Envelope {
|
||||
fn from(envelope: &himalaya_lib::Envelope) -> Self {
|
||||
Envelope {
|
||||
id: envelope.id.clone(),
|
||||
flags: envelope.flags.clone().into(),
|
||||
subject: envelope.subject.clone(),
|
||||
from: Mailbox {
|
||||
name: envelope.from.name.clone(),
|
||||
addr: envelope.from.addr.clone(),
|
||||
},
|
||||
date: envelope.date.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Table for Envelope {
|
||||
fn head() -> Row {
|
||||
|
@ -14,15 +53,29 @@ impl Table for Envelope {
|
|||
|
||||
fn row(&self) -> Row {
|
||||
let id = self.id.to_string();
|
||||
let flags = self.flags.to_symbols_string();
|
||||
let unseen = !self.flags.contains(&Flag::Seen);
|
||||
let flags = {
|
||||
let mut flags = String::new();
|
||||
flags.push_str(if !unseen { " " } else { "✷" });
|
||||
flags.push_str(if self.flags.contains(&Flag::Answered) {
|
||||
"↵"
|
||||
} else {
|
||||
" "
|
||||
});
|
||||
flags.push_str(if self.flags.contains(&Flag::Flagged) {
|
||||
"⚑"
|
||||
} else {
|
||||
" "
|
||||
});
|
||||
flags
|
||||
};
|
||||
let subject = &self.subject;
|
||||
let sender = if let Some(name) = &self.from.name {
|
||||
name
|
||||
} else {
|
||||
&self.from.addr
|
||||
};
|
||||
let date = self.date.format("%d/%m/%Y %H:%M").to_string();
|
||||
let date = self.date.to_rfc3339();
|
||||
|
||||
Row::new()
|
||||
.cell(Cell::new(id).bold_if(unseen).red())
|
||||
|
|
|
@ -1,11 +1,32 @@
|
|||
use std::ops;
|
||||
|
||||
use anyhow::Result;
|
||||
use himalaya_lib::Envelopes;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
printer::{PrintTable, PrintTableOpts, WriteColor},
|
||||
ui::Table,
|
||||
Envelope,
|
||||
};
|
||||
|
||||
/// Represents the list of envelopes.
|
||||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
pub struct Envelopes(Vec<Envelope>);
|
||||
|
||||
impl ops::Deref for Envelopes {
|
||||
type Target = Vec<Envelope>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<himalaya_lib::Envelopes> for Envelopes {
|
||||
fn from(envelopes: himalaya_lib::Envelopes) -> Self {
|
||||
Envelopes(envelopes.iter().map(Envelope::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintTable for Envelopes {
|
||||
fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
||||
writeln!(writer)?;
|
||||
|
|
|
@ -83,7 +83,11 @@ pub fn flags_arg() -> Arg {
|
|||
Arg::new(ARG_FLAGS)
|
||||
.value_name("FLAGS")
|
||||
.help("The flags")
|
||||
.long_help("The list of flags. It can be one of: seen, answered, flagged, deleted, draft, recent. Other flags are considered custom.")
|
||||
.long_help(
|
||||
"The list of flags.
|
||||
It can be one of: seen, answered, flagged, deleted, or draft.
|
||||
Other flags are considered custom.",
|
||||
)
|
||||
.num_args(1..)
|
||||
.required(true)
|
||||
.last(true)
|
||||
|
|
25
src/domain/flag/flag.rs
Normal file
25
src/domain/flag/flag.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use serde::Serialize;
|
||||
|
||||
/// Represents the flag variants.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)]
|
||||
pub enum Flag {
|
||||
Seen,
|
||||
Answered,
|
||||
Flagged,
|
||||
Deleted,
|
||||
Draft,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl From<&himalaya_lib::Flag> for Flag {
|
||||
fn from(flag: &himalaya_lib::Flag) -> Self {
|
||||
match flag {
|
||||
himalaya_lib::Flag::Seen => Flag::Seen,
|
||||
himalaya_lib::Flag::Answered => Flag::Answered,
|
||||
himalaya_lib::Flag::Flagged => Flag::Flagged,
|
||||
himalaya_lib::Flag::Deleted => Flag::Deleted,
|
||||
himalaya_lib::Flag::Draft => Flag::Draft,
|
||||
himalaya_lib::Flag::Custom(flag) => Flag::Custom(flag.clone()),
|
||||
}
|
||||
}
|
||||
}
|
21
src/domain/flag/flags.rs
Normal file
21
src/domain/flag/flags.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use serde::Serialize;
|
||||
use std::{collections::HashSet, ops};
|
||||
|
||||
use crate::Flag;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
|
||||
pub struct Flags(pub HashSet<Flag>);
|
||||
|
||||
impl ops::Deref for Flags {
|
||||
type Target = HashSet<Flag>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<himalaya_lib::Flags> for Flags {
|
||||
fn from(flags: himalaya_lib::Flags) -> Self {
|
||||
Flags(flags.iter().map(Flag::from).collect())
|
||||
}
|
||||
}
|
|
@ -1,2 +1,8 @@
|
|||
pub mod args;
|
||||
pub mod handlers;
|
||||
|
||||
pub mod flag;
|
||||
pub use flag::*;
|
||||
|
||||
pub mod flags;
|
||||
pub use flags::*;
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
use himalaya_lib::folder::Folder;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::ui::{Cell, Row, Table};
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
pub struct Folder {
|
||||
pub delim: String,
|
||||
pub name: String,
|
||||
pub desc: String,
|
||||
}
|
||||
|
||||
impl From<&himalaya_lib::Folder> for Folder {
|
||||
fn from(folder: &himalaya_lib::Folder) -> Self {
|
||||
Folder {
|
||||
delim: folder.delim.clone(),
|
||||
name: folder.name.clone(),
|
||||
desc: folder.desc.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Table for Folder {
|
||||
fn head() -> Row {
|
||||
Row::new()
|
||||
|
|
|
@ -1,11 +1,31 @@
|
|||
use std::ops;
|
||||
|
||||
use anyhow::Result;
|
||||
use himalaya_lib::folder::Folders;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
printer::{PrintTable, PrintTableOpts, WriteColor},
|
||||
ui::Table,
|
||||
Folder,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
pub struct Folders(Vec<Folder>);
|
||||
|
||||
impl ops::Deref for Folders {
|
||||
type Target = Vec<Folder>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<himalaya_lib::Folders> for Folders {
|
||||
fn from(folders: himalaya_lib::Folders) -> Self {
|
||||
Folders(folders.iter().map(Folder::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintTable for Folders {
|
||||
fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
||||
writeln!(writer)?;
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
use anyhow::Result;
|
||||
use himalaya_lib::{AccountConfig, Backend};
|
||||
|
||||
use crate::printer::{PrintTableOpts, Printer};
|
||||
use crate::{
|
||||
printer::{PrintTableOpts, Printer},
|
||||
Folders,
|
||||
};
|
||||
|
||||
pub fn expunge<P: Printer, B: Backend + ?Sized>(
|
||||
folder: &str,
|
||||
|
@ -22,7 +25,7 @@ pub fn list<P: Printer, B: Backend + ?Sized>(
|
|||
printer: &mut P,
|
||||
backend: &mut B,
|
||||
) -> Result<()> {
|
||||
let folders = backend.list_folders()?;
|
||||
let folders: Folders = backend.list_folders()?.into();
|
||||
printer.print_table(
|
||||
// TODO: remove Box
|
||||
Box::new(folders),
|
||||
|
|
Loading…
Reference in a new issue