parent
c6f1fa9be0
commit
f632bc4c08
|
@ -92,7 +92,6 @@ pub trait MailListingTrait: ListingTrait {
|
||||||
StatusEvent::DisplayMessage(e.to_string()),
|
StatusEvent::DisplayMessage(e.to_string()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.row_updates().push(thread_hash);
|
|
||||||
}
|
}
|
||||||
ListingAction::SetUnseen => {
|
ListingAction::SetUnseen => {
|
||||||
if let Err(e) = envelope.set_unseen(op) {
|
if let Err(e) = envelope.set_unseen(op) {
|
||||||
|
@ -153,8 +152,7 @@ pub trait MailListingTrait: ListingTrait {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn row_updates(&mut self) -> &mut StackVec<ThreadHash>;
|
fn row_updates(&mut self) -> &mut StackVec<ThreadHash>;
|
||||||
|
fn get_focused_items(&self, _context: &Context) -> StackVec<ThreadHash>;
|
||||||
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ListingTrait: Component {
|
pub trait ListingTrait: Component {
|
||||||
|
@ -508,6 +506,17 @@ impl Component for Listing {
|
||||||
self.component.set_style(IndexStyle::Conversations);
|
self.component.set_style(IndexStyle::Conversations);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Action::Listing(a @ ListingAction::SetSeen)
|
||||||
|
| Action::Listing(a @ ListingAction::SetUnseen)
|
||||||
|
| Action::Listing(a @ ListingAction::Delete)
|
||||||
|
| Action::Listing(a @ ListingAction::Tag(_)) => {
|
||||||
|
let focused = self.component.get_focused_items(context);
|
||||||
|
for i in focused {
|
||||||
|
self.component.perform_action(context, i, a);
|
||||||
|
}
|
||||||
|
self.component.set_dirty();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
UIEvent::RefreshMailbox((idxa, folder_hash)) => {
|
UIEvent::RefreshMailbox((idxa, folder_hash)) => {
|
||||||
|
|
|
@ -79,68 +79,23 @@ impl MailListingTrait for CompactListing {
|
||||||
&mut self.row_updates
|
&mut self.row_updates
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
|
||||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
|
||||||
let threads = &account.collection.threads[&folder_hash];
|
let cursor_iter;
|
||||||
if let Some(env_hash) = threads[&thread_hash].message() {
|
let sel_iter = if is_selection_empty {
|
||||||
if !account.contains_key(env_hash) {
|
cursor_iter = None;
|
||||||
/* The envelope has been renamed or removed, so wait for the appropriate event to
|
Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k))
|
||||||
* arrive */
|
} else {
|
||||||
return;
|
cursor_iter = Some(i.iter());
|
||||||
}
|
None
|
||||||
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
};
|
||||||
let has_attachments = envelope.has_attachments();
|
let iter = sel_iter
|
||||||
drop(envelope);
|
.into_iter()
|
||||||
let fg_color = if threads[&thread_hash].has_unseen() {
|
.flatten()
|
||||||
Color::Byte(0)
|
.chain(cursor_iter.into_iter().flatten())
|
||||||
} else {
|
.cloned();
|
||||||
Color::Default
|
StackVec::from_iter(iter.into_iter())
|
||||||
};
|
|
||||||
let idx = self.order[&thread_hash];
|
|
||||||
let bg_color = if context.settings.terminal.theme == "light" {
|
|
||||||
if threads[&thread_hash].has_unseen() {
|
|
||||||
Color::Byte(251)
|
|
||||||
} else if idx % 2 == 0 {
|
|
||||||
Color::Byte(252)
|
|
||||||
} else {
|
|
||||||
Color::Default
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if threads[&thread_hash].has_unseen() {
|
|
||||||
Color::Byte(253)
|
|
||||||
} else if idx % 2 == 0 {
|
|
||||||
Color::Byte(236)
|
|
||||||
} else {
|
|
||||||
Color::Default
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for i in 0..self.data_columns.columns.len() {
|
|
||||||
let column_width = self.data_columns.columns[i].size().0;
|
|
||||||
if column_width == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
change_colors(
|
|
||||||
&mut self.data_columns.columns[i],
|
|
||||||
((0, idx), (column_width - 1, idx)),
|
|
||||||
fg_color,
|
|
||||||
bg_color,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
match (threads.is_snoozed(thread_hash), has_attachments) {
|
|
||||||
(true, true) => {
|
|
||||||
self.data_columns.columns[3][(0, idx)].set_fg(Color::Byte(103));
|
|
||||||
self.data_columns.columns[3][(2, idx)].set_fg(Color::Red);
|
|
||||||
}
|
|
||||||
(true, false) => {
|
|
||||||
self.data_columns.columns[3][(0, idx)].set_fg(Color::Red);
|
|
||||||
}
|
|
||||||
(false, true) => {
|
|
||||||
self.data_columns.columns[3][(0, idx)].set_fg(Color::Byte(103));
|
|
||||||
}
|
|
||||||
(false, false) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +519,7 @@ impl CompactListing {
|
||||||
}
|
}
|
||||||
fn make_entry_string(
|
fn make_entry_string(
|
||||||
&self,
|
&self,
|
||||||
e: EnvelopeRef,
|
e: &Envelope,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
thread_node: &ThreadNode,
|
thread_node: &ThreadNode,
|
||||||
is_snoozed: bool,
|
is_snoozed: bool,
|
||||||
|
@ -592,10 +547,16 @@ impl CompactListing {
|
||||||
tags.push(' ');
|
tags.push(' ');
|
||||||
tags.push_str(tags_lck.get(t).as_ref().unwrap());
|
tags.push_str(tags_lck.get(t).as_ref().unwrap());
|
||||||
tags.push(' ');
|
tags.push(' ');
|
||||||
if let Some(&c) = context.settings.tags.colors.get(t) {
|
if let Some(&c) = folder
|
||||||
|
.conf_override
|
||||||
|
.tags
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| s.colors.get(t))
|
||||||
|
.unwrap_or(None)
|
||||||
|
{
|
||||||
colors.push(c);
|
colors.push(c);
|
||||||
} else {
|
} else {
|
||||||
colors.push(8);
|
colors.push(Color::Byte(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !tags.is_empty() {
|
if !tags.is_empty() {
|
||||||
|
@ -732,7 +693,7 @@ impl CompactListing {
|
||||||
context.accounts[self.cursor_pos.0].collection.get_env(i);
|
context.accounts[self.cursor_pos.0].collection.get_env(i);
|
||||||
|
|
||||||
let entry_strings = self.make_entry_string(
|
let entry_strings = self.make_entry_string(
|
||||||
root_envelope,
|
&root_envelope,
|
||||||
context,
|
context,
|
||||||
thread_node,
|
thread_node,
|
||||||
threads.is_snoozed(root_idx),
|
threads.is_snoozed(root_idx),
|
||||||
|
@ -885,14 +846,14 @@ impl CompactListing {
|
||||||
t,
|
t,
|
||||||
&mut self.data_columns.columns[4],
|
&mut self.data_columns.columns[4],
|
||||||
Color::White,
|
Color::White,
|
||||||
Color::Byte(color),
|
color,
|
||||||
Attr::Bold,
|
Attr::Bold,
|
||||||
((x + 1, idx), (min_width.4, idx)),
|
((x + 1, idx), (min_width.4, idx)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
self.data_columns.columns[4][(x, idx)].set_bg(Color::Byte(color));
|
self.data_columns.columns[4][(x, idx)].set_bg(color);
|
||||||
if _x < min_width.4 {
|
if _x < min_width.4 {
|
||||||
self.data_columns.columns[4][(_x, idx)].set_bg(Color::Byte(color));
|
self.data_columns.columns[4][(_x, idx)].set_bg(color);
|
||||||
self.data_columns.columns[4][(_x, idx)].set_keep_bg(true);
|
self.data_columns.columns[4][(_x, idx)].set_keep_bg(true);
|
||||||
}
|
}
|
||||||
for x in (x + 1).._x {
|
for x in (x + 1).._x {
|
||||||
|
@ -905,6 +866,7 @@ impl CompactListing {
|
||||||
x
|
x
|
||||||
};
|
};
|
||||||
for x in x..min_width.4 {
|
for x in x..min_width.4 {
|
||||||
|
self.data_columns.columns[4][(x, idx)].set_ch(' ');
|
||||||
self.data_columns.columns[4][(x, idx)].set_bg(bg_color);
|
self.data_columns.columns[4][(x, idx)].set_bg(bg_color);
|
||||||
}
|
}
|
||||||
match (
|
match (
|
||||||
|
@ -958,6 +920,163 @@ impl CompactListing {
|
||||||
self.filtered_selection[cursor]
|
self.filtered_selection[cursor]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
||||||
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
|
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||||
|
let threads = &account.collection.threads[&folder_hash];
|
||||||
|
if let Some(env_hash) = threads[&thread_hash].message() {
|
||||||
|
if !account.contains_key(env_hash) {
|
||||||
|
/* The envelope has been renamed or removed, so wait for the appropriate event to
|
||||||
|
* arrive */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
||||||
|
let has_attachments = envelope.has_attachments();
|
||||||
|
let fg_color = if threads[&thread_hash].has_unseen() {
|
||||||
|
Color::Byte(0)
|
||||||
|
} else {
|
||||||
|
Color::Default
|
||||||
|
};
|
||||||
|
let idx = self.order[&thread_hash];
|
||||||
|
let bg_color = if context.settings.terminal.theme == "light" {
|
||||||
|
if threads[&thread_hash].has_unseen() {
|
||||||
|
Color::Byte(251)
|
||||||
|
} else if idx % 2 == 0 {
|
||||||
|
Color::Byte(252)
|
||||||
|
} else {
|
||||||
|
Color::Default
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if threads[&thread_hash].has_unseen() {
|
||||||
|
Color::Byte(253)
|
||||||
|
} else if idx % 2 == 0 {
|
||||||
|
Color::Byte(236)
|
||||||
|
} else {
|
||||||
|
Color::Default
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let strings = self.make_entry_string(
|
||||||
|
&envelope,
|
||||||
|
context,
|
||||||
|
&threads[&thread_hash],
|
||||||
|
threads.is_snoozed(thread_hash),
|
||||||
|
);
|
||||||
|
drop(envelope);
|
||||||
|
let columns = &mut self.data_columns.columns;
|
||||||
|
let min_width = (
|
||||||
|
columns[0].size().0,
|
||||||
|
columns[1].size().0,
|
||||||
|
columns[2].size().0,
|
||||||
|
columns[3].size().0,
|
||||||
|
columns[4].size().0,
|
||||||
|
);
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&idx.to_string(),
|
||||||
|
&mut columns[0],
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, idx), (min_width.0, idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in columns[0].row_iter((x, min_width.0.saturating_sub(1)), idx) {
|
||||||
|
columns[0][c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.date,
|
||||||
|
&mut columns[1],
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, idx), (min_width.1.saturating_sub(1), idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in columns[1].row_iter((x, min_width.1.saturating_sub(1)), idx) {
|
||||||
|
columns[1][c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.from,
|
||||||
|
&mut columns[2],
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, idx), (min_width.2, idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in columns[2].row_iter((x, min_width.2.saturating_sub(1)), idx) {
|
||||||
|
columns[2][c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.flag,
|
||||||
|
&mut columns[3],
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, idx), (min_width.3, idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in columns[3].row_iter((x, min_width.3.saturating_sub(1)), idx) {
|
||||||
|
columns[3][c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.subject,
|
||||||
|
&mut columns[4],
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, idx), (min_width.4, idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let x = {
|
||||||
|
let mut x = x + 1;
|
||||||
|
for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) {
|
||||||
|
let (_x, _) = write_string_to_grid(
|
||||||
|
t,
|
||||||
|
&mut columns[4],
|
||||||
|
Color::White,
|
||||||
|
color,
|
||||||
|
Attr::Bold,
|
||||||
|
((x + 1, idx), (min_width.4, idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in columns[4].row_iter((x, x), idx) {
|
||||||
|
columns[4][c].set_bg(color);
|
||||||
|
}
|
||||||
|
for c in columns[4].row_iter((_x, _x), idx) {
|
||||||
|
columns[4][c].set_bg(color);
|
||||||
|
columns[4][c].set_keep_bg(true);
|
||||||
|
}
|
||||||
|
for c in columns[4].row_iter((x + 1, _x), idx) {
|
||||||
|
columns[4][c].set_keep_fg(true);
|
||||||
|
columns[4][c].set_keep_bg(true);
|
||||||
|
}
|
||||||
|
for c in columns[4].row_iter((x, x), idx) {
|
||||||
|
columns[4][c].set_keep_bg(true);
|
||||||
|
}
|
||||||
|
x = _x + 1;
|
||||||
|
}
|
||||||
|
x
|
||||||
|
};
|
||||||
|
for c in columns[4].row_iter((x, min_width.4.saturating_sub(1)), idx) {
|
||||||
|
columns[4][c].set_ch(' ');
|
||||||
|
columns[4][c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
match (threads.is_snoozed(thread_hash), has_attachments) {
|
||||||
|
(true, true) => {
|
||||||
|
columns[3][(0, idx)].set_fg(Color::Byte(103));
|
||||||
|
columns[3][(2, idx)].set_fg(Color::Red);
|
||||||
|
}
|
||||||
|
(true, false) => {
|
||||||
|
columns[3][(0, idx)].set_fg(Color::Red);
|
||||||
|
}
|
||||||
|
(false, true) => {
|
||||||
|
columns[3][(0, idx)].set_fg(Color::Byte(103));
|
||||||
|
}
|
||||||
|
(false, false) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for CompactListing {
|
impl Component for CompactListing {
|
||||||
|
@ -1132,38 +1251,6 @@ impl Component for CompactListing {
|
||||||
self.refresh_mailbox(context);
|
self.refresh_mailbox(context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Action::Listing(a @ ListingAction::SetSeen)
|
|
||||||
| Action::Listing(a @ ListingAction::SetUnseen)
|
|
||||||
| Action::Listing(a @ ListingAction::Delete)
|
|
||||||
| Action::Listing(a @ ListingAction::Tag(_))
|
|
||||||
if !self.unfocused =>
|
|
||||||
{
|
|
||||||
let is_selection_empty =
|
|
||||||
self.selection.values().cloned().any(std::convert::identity);
|
|
||||||
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
|
|
||||||
let cursor_iter;
|
|
||||||
let sel_iter = if is_selection_empty {
|
|
||||||
cursor_iter = None;
|
|
||||||
Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k))
|
|
||||||
} else {
|
|
||||||
cursor_iter = Some(i.iter());
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let iter = sel_iter
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.chain(cursor_iter.into_iter().flatten())
|
|
||||||
.cloned();
|
|
||||||
let stack = StackVec::from_iter(iter.into_iter());
|
|
||||||
for i in stack {
|
|
||||||
self.perform_action(context, i, a);
|
|
||||||
}
|
|
||||||
self.dirty = true;
|
|
||||||
for v in self.selection.values_mut() {
|
|
||||||
*v = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
|
|
@ -73,7 +73,7 @@ column_str!(struct DateString(String));
|
||||||
column_str!(struct FromString(String));
|
column_str!(struct FromString(String));
|
||||||
column_str!(struct SubjectString(String));
|
column_str!(struct SubjectString(String));
|
||||||
column_str!(struct FlagString(String));
|
column_str!(struct FlagString(String));
|
||||||
column_str!(struct TagString(String, StackVec<u8>));
|
column_str!(struct TagString(String, StackVec<Color>));
|
||||||
|
|
||||||
/// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a
|
/// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a
|
||||||
/// `ThreadView`.
|
/// `ThreadView`.
|
||||||
|
@ -111,43 +111,26 @@ impl MailListingTrait for ConversationsListing {
|
||||||
&mut self.row_updates
|
&mut self.row_updates
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> {
|
||||||
let account = &context.accounts[self.cursor_pos.0];
|
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
|
||||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
|
||||||
let threads = &account.collection.threads[&folder_hash];
|
let cursor_iter;
|
||||||
let thread_node = &threads.thread_nodes[&thread_hash];
|
let sel_iter = if is_selection_empty {
|
||||||
let row: usize = self.order[&thread_hash];
|
cursor_iter = None;
|
||||||
let width = self.content.size().0;
|
Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k))
|
||||||
|
|
||||||
let fg_color = if thread_node.has_unseen() {
|
|
||||||
Color::Byte(0)
|
|
||||||
} else {
|
} else {
|
||||||
Color::Default
|
cursor_iter = Some(i.iter());
|
||||||
|
None
|
||||||
};
|
};
|
||||||
let bg_color = if thread_node.has_unseen() {
|
let iter = sel_iter
|
||||||
Color::Byte(251)
|
.into_iter()
|
||||||
} else {
|
.flatten()
|
||||||
Color::Default
|
.chain(cursor_iter.into_iter().flatten())
|
||||||
};
|
.cloned();
|
||||||
change_colors(
|
StackVec::from_iter(iter.into_iter())
|
||||||
&mut self.content,
|
|
||||||
((0, 3 * row), (width - 1, 3 * row + 1)),
|
|
||||||
fg_color,
|
|
||||||
bg_color,
|
|
||||||
);
|
|
||||||
let padding_fg = if context.settings.terminal.theme == "light" {
|
|
||||||
Color::Byte(254)
|
|
||||||
} else {
|
|
||||||
Color::Byte(235)
|
|
||||||
};
|
|
||||||
change_colors(
|
|
||||||
&mut self.content,
|
|
||||||
((0, 3 * row + 2), (width - 1, 3 * row + 2)),
|
|
||||||
padding_fg,
|
|
||||||
bg_color,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ListingTrait for ConversationsListing {
|
impl ListingTrait for ConversationsListing {
|
||||||
fn coordinates(&self) -> (usize, usize) {
|
fn coordinates(&self) -> (usize, usize) {
|
||||||
(self.new_cursor_pos.0, self.new_cursor_pos.1)
|
(self.new_cursor_pos.0, self.new_cursor_pos.1)
|
||||||
|
@ -559,10 +542,16 @@ impl ConversationsListing {
|
||||||
tags.push(' ');
|
tags.push(' ');
|
||||||
tags.push_str(tags_lck.get(t).as_ref().unwrap());
|
tags.push_str(tags_lck.get(t).as_ref().unwrap());
|
||||||
tags.push(' ');
|
tags.push(' ');
|
||||||
if let Some(&c) = context.settings.tags.colors.get(t) {
|
if let Some(&c) = folder
|
||||||
|
.conf_override
|
||||||
|
.tags
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| s.colors.get(t))
|
||||||
|
.unwrap_or(None)
|
||||||
|
{
|
||||||
colors.push(c);
|
colors.push(c);
|
||||||
} else {
|
} else {
|
||||||
colors.push(8);
|
colors.push(Color::Byte(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !tags.is_empty() {
|
if !tags.is_empty() {
|
||||||
|
@ -830,14 +819,14 @@ impl ConversationsListing {
|
||||||
t,
|
t,
|
||||||
&mut self.content,
|
&mut self.content,
|
||||||
Color::White,
|
Color::White,
|
||||||
Color::Byte(color),
|
color,
|
||||||
Attr::Bold,
|
Attr::Bold,
|
||||||
((x + 1, 3 * idx), (width - 1, 3 * idx)),
|
((x + 1, 3 * idx), (width - 1, 3 * idx)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
self.content[(x, 3 * idx)].set_bg(Color::Byte(color));
|
self.content[(x, 3 * idx)].set_bg(color);
|
||||||
if _x < width {
|
if _x < width {
|
||||||
self.content[(_x, 3 * idx)].set_bg(Color::Byte(color));
|
self.content[(_x, 3 * idx)].set_bg(color);
|
||||||
self.content[(_x, 3 * idx)].set_keep_bg(true);
|
self.content[(_x, 3 * idx)].set_keep_bg(true);
|
||||||
}
|
}
|
||||||
for x in (x + 1).._x {
|
for x in (x + 1).._x {
|
||||||
|
@ -848,6 +837,7 @@ impl ConversationsListing {
|
||||||
x = _x + 1;
|
x = _x + 1;
|
||||||
}
|
}
|
||||||
for x in x..width {
|
for x in x..width {
|
||||||
|
self.content[(x, 3 * idx)].set_ch(' ');
|
||||||
self.content[(x, 3 * idx)].set_bg(bg_color);
|
self.content[(x, 3 * idx)].set_bg(bg_color);
|
||||||
}
|
}
|
||||||
/* Next line, draw date */
|
/* Next line, draw date */
|
||||||
|
@ -940,6 +930,164 @@ impl ConversationsListing {
|
||||||
self.filtered_selection[cursor]
|
self.filtered_selection[cursor]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
|
||||||
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
|
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||||
|
let threads = &account.collection.threads[&folder_hash];
|
||||||
|
let thread_node = &threads.thread_nodes[&thread_hash];
|
||||||
|
let idx: usize = self.order[&thread_hash];
|
||||||
|
let width = self.content.size().0;
|
||||||
|
|
||||||
|
let fg_color = if thread_node.has_unseen() {
|
||||||
|
Color::Byte(0)
|
||||||
|
} else {
|
||||||
|
Color::Default
|
||||||
|
};
|
||||||
|
let bg_color = if thread_node.has_unseen() {
|
||||||
|
Color::Byte(251)
|
||||||
|
} else {
|
||||||
|
Color::Default
|
||||||
|
};
|
||||||
|
let padding_fg = if context.settings.terminal.theme == "light" {
|
||||||
|
Color::Byte(254)
|
||||||
|
} else {
|
||||||
|
Color::Byte(235)
|
||||||
|
};
|
||||||
|
let mut from_address_list = Vec::new();
|
||||||
|
let mut from_address_set: std::collections::HashSet<Vec<u8>> =
|
||||||
|
std::collections::HashSet::new();
|
||||||
|
let mut stack = StackVec::new();
|
||||||
|
stack.push(thread_hash);
|
||||||
|
while let Some(h) = stack.pop() {
|
||||||
|
let env_hash = if let Some(h) = threads.thread_nodes()[&h].message() {
|
||||||
|
h
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
let envelope: &EnvelopeRef = &context.accounts[self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.get_env(env_hash);
|
||||||
|
for addr in envelope.from().iter() {
|
||||||
|
if from_address_set.contains(addr.raw()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
from_address_set.insert(addr.raw().to_vec());
|
||||||
|
from_address_list.push(addr.clone());
|
||||||
|
}
|
||||||
|
for c in threads.thread_nodes()[&h].children() {
|
||||||
|
stack.push(*c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let env_hash = threads[&thread_hash].message().unwrap();
|
||||||
|
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
||||||
|
let strings = self.make_entry_string(
|
||||||
|
&envelope,
|
||||||
|
context,
|
||||||
|
&from_address_list,
|
||||||
|
&threads[&thread_hash],
|
||||||
|
threads.is_snoozed(thread_hash),
|
||||||
|
);
|
||||||
|
drop(envelope);
|
||||||
|
/* draw flags */
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.flag,
|
||||||
|
&mut self.content,
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, 3 * idx), (width - 1, 3 * idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in self.content.row_iter((x, x + 3), 3 * idx) {
|
||||||
|
self.content[c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
/* draw subject */
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.subject,
|
||||||
|
&mut self.content,
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Bold,
|
||||||
|
((x, 3 * idx), (width - 1, 3 * idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let x = {
|
||||||
|
let mut x = x + 1;
|
||||||
|
for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) {
|
||||||
|
let (_x, _) = write_string_to_grid(
|
||||||
|
t,
|
||||||
|
&mut self.content,
|
||||||
|
Color::White,
|
||||||
|
color,
|
||||||
|
Attr::Bold,
|
||||||
|
((x + 1, 3 * idx), (width - 1, 3 * idx)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in self.content.row_iter((x, x), 3 * idx) {
|
||||||
|
self.content[c].set_bg(color);
|
||||||
|
}
|
||||||
|
for c in self.content.row_iter((_x, _x), 3 * idx) {
|
||||||
|
self.content[c].set_bg(color);
|
||||||
|
self.content[c].set_keep_bg(true);
|
||||||
|
}
|
||||||
|
for c in self.content.row_iter((x + 1, _x), 3 * idx) {
|
||||||
|
self.content[c].set_keep_fg(true);
|
||||||
|
self.content[c].set_keep_bg(true);
|
||||||
|
}
|
||||||
|
for c in self.content.row_iter((x, x), 3 * idx) {
|
||||||
|
self.content[c].set_keep_bg(true);
|
||||||
|
}
|
||||||
|
x = _x + 1;
|
||||||
|
}
|
||||||
|
x
|
||||||
|
};
|
||||||
|
for c in self.content.row_iter((x, width.saturating_sub(1)), 3 * idx) {
|
||||||
|
self.content[c].set_ch(' ');
|
||||||
|
self.content[c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
/* Next line, draw date */
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.date,
|
||||||
|
&mut self.content,
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((0, 3 * idx + 1), (width - 1, 3 * idx + 1)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
for c in self.content.row_iter((x, x + 4), 3 * idx + 1) {
|
||||||
|
self.content[c].set_ch('▁');
|
||||||
|
self.content[c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
/* draw from */
|
||||||
|
let (x, _) = write_string_to_grid(
|
||||||
|
&strings.from,
|
||||||
|
&mut self.content,
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
Attr::Default,
|
||||||
|
((x + 4, 3 * idx + 1), (width - 1, 3 * idx + 1)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
for c in self
|
||||||
|
.content
|
||||||
|
.row_iter((x, width.saturating_sub(1)), 3 * idx + 1)
|
||||||
|
{
|
||||||
|
self.content[c].set_ch('▁');
|
||||||
|
self.content[c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
for c in self
|
||||||
|
.content
|
||||||
|
.row_iter((0, width.saturating_sub(1)), 3 * idx + 2)
|
||||||
|
{
|
||||||
|
self.content[c].set_ch('▓');
|
||||||
|
self.content[c].set_fg(padding_fg);
|
||||||
|
self.content[c].set_bg(bg_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for ConversationsListing {
|
impl Component for ConversationsListing {
|
||||||
|
@ -1191,37 +1339,6 @@ impl Component for ConversationsListing {
|
||||||
self.refresh_mailbox(context);
|
self.refresh_mailbox(context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Action::Listing(a @ ListingAction::SetSeen)
|
|
||||||
| Action::Listing(a @ ListingAction::SetUnseen)
|
|
||||||
| Action::Listing(a @ ListingAction::Delete)
|
|
||||||
if !self.unfocused =>
|
|
||||||
{
|
|
||||||
let is_selection_empty =
|
|
||||||
self.selection.values().cloned().any(std::convert::identity);
|
|
||||||
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
|
|
||||||
let cursor_iter;
|
|
||||||
let sel_iter = if is_selection_empty {
|
|
||||||
cursor_iter = None;
|
|
||||||
Some(self.selection.iter().filter(|(_, v)| **v).map(|(k, _)| k))
|
|
||||||
} else {
|
|
||||||
cursor_iter = Some(i.iter());
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let iter = sel_iter
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.chain(cursor_iter.into_iter().flatten())
|
|
||||||
.cloned();
|
|
||||||
let stack = StackVec::from_iter(iter.into_iter());
|
|
||||||
for i in stack {
|
|
||||||
self.perform_action(context, i, a);
|
|
||||||
}
|
|
||||||
self.dirty = true;
|
|
||||||
for v in self.selection.values_mut() {
|
|
||||||
*v = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -62,6 +62,7 @@ pub struct PlainListing {
|
||||||
filtered_selection: Vec<EnvelopeHash>,
|
filtered_selection: Vec<EnvelopeHash>,
|
||||||
filtered_order: FnvHashMap<EnvelopeHash, usize>,
|
filtered_order: FnvHashMap<EnvelopeHash, usize>,
|
||||||
selection: FnvHashMap<EnvelopeHash, bool>,
|
selection: FnvHashMap<EnvelopeHash, bool>,
|
||||||
|
thread_hashes: FnvHashMap<EnvelopeHash, ThreadHash>,
|
||||||
local_collection: Vec<EnvelopeHash>,
|
local_collection: Vec<EnvelopeHash>,
|
||||||
/// If we must redraw on next redraw event
|
/// If we must redraw on next redraw event
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
|
@ -81,7 +82,20 @@ impl MailListingTrait for PlainListing {
|
||||||
&mut self._row_updates
|
&mut self._row_updates
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_line(&mut self, _context: &Context, _thread_hash: ThreadHash) {}
|
fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> {
|
||||||
|
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
|
||||||
|
if is_selection_empty {
|
||||||
|
self.selection
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, v)| **v)
|
||||||
|
.map(|(k, _)| self.thread_hashes[k])
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
let mut ret = StackVec::new();
|
||||||
|
ret.push(self.get_thread_under_cursor(self.cursor_pos.2, context));
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ListingTrait for PlainListing {
|
impl ListingTrait for PlainListing {
|
||||||
|
@ -470,6 +484,7 @@ impl PlainListing {
|
||||||
subsort: (SortField::Date, SortOrder::Desc),
|
subsort: (SortField::Date, SortOrder::Desc),
|
||||||
all_envelopes: fnv::FnvHashSet::default(),
|
all_envelopes: fnv::FnvHashSet::default(),
|
||||||
local_collection: Vec::new(),
|
local_collection: Vec::new(),
|
||||||
|
thread_hashes: FnvHashMap::default(),
|
||||||
order: FnvHashMap::default(),
|
order: FnvHashMap::default(),
|
||||||
filter_term: String::new(),
|
filter_term: String::new(),
|
||||||
filtered_selection: Vec::new(),
|
filtered_selection: Vec::new(),
|
||||||
|
@ -520,7 +535,7 @@ impl PlainListing {
|
||||||
{
|
{
|
||||||
colors.push(c);
|
colors.push(c);
|
||||||
} else {
|
} else {
|
||||||
colors.push(8);
|
colors.push(Color::Byte(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !tags.is_empty() {
|
if !tags.is_empty() {
|
||||||
|
@ -587,6 +602,18 @@ impl PlainListing {
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
let env_lck = context.accounts[self.cursor_pos.0]
|
||||||
|
.collection
|
||||||
|
.envelopes
|
||||||
|
.read()
|
||||||
|
.unwrap();
|
||||||
|
self.thread_hashes = context.accounts[self.cursor_pos.0][folder_hash]
|
||||||
|
.unwrap()
|
||||||
|
.envelopes
|
||||||
|
.iter()
|
||||||
|
.map(|h| (*h, env_lck[h].thread()))
|
||||||
|
.collect();
|
||||||
|
drop(env_lck);
|
||||||
self.redraw_list(context);
|
self.redraw_list(context);
|
||||||
|
|
||||||
if self.length > 0 {
|
if self.length > 0 {
|
||||||
|
@ -803,16 +830,16 @@ impl PlainListing {
|
||||||
t,
|
t,
|
||||||
&mut columns[4],
|
&mut columns[4],
|
||||||
Color::White,
|
Color::White,
|
||||||
Color::Byte(color),
|
color,
|
||||||
Attr::Bold,
|
Attr::Bold,
|
||||||
((x + 1, idx), (min_width.4, idx)),
|
((x + 1, idx), (min_width.4, idx)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
for c in columns[4].row_iter((x, x), idx) {
|
for c in columns[4].row_iter((x, x), idx) {
|
||||||
columns[4][c].set_bg(Color::Byte(color));
|
columns[4][c].set_bg(color);
|
||||||
}
|
}
|
||||||
for c in columns[4].row_iter((_x, _x), idx) {
|
for c in columns[4].row_iter((_x, _x), idx) {
|
||||||
columns[4][c].set_bg(Color::Byte(color));
|
columns[4][c].set_bg(color);
|
||||||
columns[4][c].set_keep_bg(true);
|
columns[4][c].set_keep_bg(true);
|
||||||
}
|
}
|
||||||
for c in columns[4].row_iter((x + 1, _x), idx) {
|
for c in columns[4].row_iter((x + 1, _x), idx) {
|
||||||
|
@ -866,6 +893,12 @@ impl PlainListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash {
|
||||||
|
let account = &context.accounts[self.cursor_pos.0];
|
||||||
|
let env_hash = self.get_env_under_cursor(cursor, context);
|
||||||
|
account.collection.get_env(env_hash).thread()
|
||||||
|
}
|
||||||
|
|
||||||
fn format_date(envelope: &Envelope) -> String {
|
fn format_date(envelope: &Envelope) -> String {
|
||||||
let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(envelope.date());
|
let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(envelope.date());
|
||||||
let now: std::time::Duration = std::time::SystemTime::now()
|
let now: std::time::Duration = std::time::SystemTime::now()
|
||||||
|
|
|
@ -54,7 +54,9 @@ impl MailListingTrait for ThreadListing {
|
||||||
&mut self.row_updates
|
&mut self.row_updates
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_line(&mut self, _context: &Context, _thread_hash: ThreadHash) {}
|
fn get_focused_items(&self, _context: &Context) -> StackVec<ThreadHash> {
|
||||||
|
StackVec::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ListingTrait for ThreadListing {
|
impl ListingTrait for ThreadListing {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use crate::terminal::Color;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};
|
use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
|
@ -26,7 +27,7 @@ use std::hash::Hasher;
|
||||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||||
pub struct TagsSettings {
|
pub struct TagsSettings {
|
||||||
#[serde(default, deserialize_with = "tag_color_de")]
|
#[serde(default, deserialize_with = "tag_color_de")]
|
||||||
pub colors: HashMap<u64, u8>,
|
pub colors: HashMap<u64, Color>,
|
||||||
#[serde(default, deserialize_with = "tag_set_de")]
|
#[serde(default, deserialize_with = "tag_set_de")]
|
||||||
pub ignore_tags: HashSet<u64>,
|
pub ignore_tags: HashSet<u64>,
|
||||||
}
|
}
|
||||||
|
@ -54,16 +55,29 @@ where
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tag_color_de<'de, D>(deserializer: D) -> std::result::Result<HashMap<u64, u8>, D::Error>
|
pub fn tag_color_de<'de, D>(deserializer: D) -> std::result::Result<HashMap<u64, Color>, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
Ok(<HashMap<String, u8>>::deserialize(deserializer)?
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum _Color {
|
||||||
|
B(u8),
|
||||||
|
C(Color),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(<HashMap<String, _Color>>::deserialize(deserializer)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(tag, color)| {
|
.map(|(tag, color)| {
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
hasher.write(tag.as_bytes());
|
hasher.write(tag.as_bytes());
|
||||||
(hasher.finish(), color)
|
(
|
||||||
|
hasher.finish(),
|
||||||
|
match color {
|
||||||
|
_Color::B(b) => Color::Byte(b),
|
||||||
|
_Color::C(c) => c,
|
||||||
|
},
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ use super::position::*;
|
||||||
use crate::state::Context;
|
use crate::state::Context;
|
||||||
use text_processing::wcwidth;
|
use text_processing::wcwidth;
|
||||||
|
|
||||||
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||||
|
@ -740,6 +741,614 @@ impl Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Color {
|
||||||
|
fn default() -> Self {
|
||||||
|
Color::Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Color {
|
||||||
|
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
if let Ok(s) = <String>::deserialize(deserializer) {
|
||||||
|
let byte = match s.as_str() {
|
||||||
|
"Aqua" => 14,
|
||||||
|
"Aquamarine1" => 122,
|
||||||
|
"Aquamarine2" => 86,
|
||||||
|
"Aquamarine3" => 79,
|
||||||
|
"Black" => 0,
|
||||||
|
"Blue" => 12,
|
||||||
|
"Blue1" => 21,
|
||||||
|
"Blue2" => 19,
|
||||||
|
"Blue3" => 20,
|
||||||
|
"BlueViolet" => 57,
|
||||||
|
"CadetBlue" => 72,
|
||||||
|
"CadetBlue1" => 73,
|
||||||
|
"Chartreuse1" => 118,
|
||||||
|
"Chartreuse2" => 112,
|
||||||
|
"Chartreuse3" => 82,
|
||||||
|
"Chartreuse4" => 70,
|
||||||
|
"Chartreuse5" => 76,
|
||||||
|
"Chartreuse6" => 64,
|
||||||
|
"CornflowerBlue" => 69,
|
||||||
|
"Cornsilk1" => 230,
|
||||||
|
"Cyan1" => 51,
|
||||||
|
"Cyan2" => 50,
|
||||||
|
"Cyan3" => 43,
|
||||||
|
"DarkBlue" => 18,
|
||||||
|
"DarkCyan" => 36,
|
||||||
|
"DarkGoldenrod" => 136,
|
||||||
|
"DarkGreen" => 22,
|
||||||
|
"DarkKhaki" => 143,
|
||||||
|
"DarkMagenta" => 90,
|
||||||
|
"DarkMagenta1" => 91,
|
||||||
|
"DarkOliveGreen1" => 192,
|
||||||
|
"DarkOliveGreen2" => 155,
|
||||||
|
"DarkOliveGreen3" => 191,
|
||||||
|
"DarkOliveGreen4" => 107,
|
||||||
|
"DarkOliveGreen5" => 113,
|
||||||
|
"DarkOliveGreen6" => 149,
|
||||||
|
"DarkOrange" => 208,
|
||||||
|
"DarkOrange2" => 130,
|
||||||
|
"DarkOrange3" => 166,
|
||||||
|
"DarkRed" => 52,
|
||||||
|
"DarkRed2" => 88,
|
||||||
|
"DarkSeaGreen" => 108,
|
||||||
|
"DarkSeaGreen1" => 158,
|
||||||
|
"DarkSeaGreen2" => 193,
|
||||||
|
"DarkSeaGreen3" => 151,
|
||||||
|
"DarkSeaGreen4" => 157,
|
||||||
|
"DarkSeaGreen5" => 115,
|
||||||
|
"DarkSeaGreen6" => 150,
|
||||||
|
"DarkSeaGreen7" => 65,
|
||||||
|
"DarkSeaGreen8" => 71,
|
||||||
|
"DarkSlateGray1" => 123,
|
||||||
|
"DarkSlateGray2" => 87,
|
||||||
|
"DarkSlateGray3" => 116,
|
||||||
|
"DarkTurquoise" => 44,
|
||||||
|
"DarkViolet" => 128,
|
||||||
|
"DarkViolet1" => 92,
|
||||||
|
"DeepPink1" => 199,
|
||||||
|
"DeepPink2" => 197,
|
||||||
|
"DeepPink3" => 198,
|
||||||
|
"DeepPink4" => 125,
|
||||||
|
"DeepPink6" => 162,
|
||||||
|
"DeepPink7" => 89,
|
||||||
|
"DeepPink8" => 53,
|
||||||
|
"DeepPink9" => 161,
|
||||||
|
"DeepSkyBlue1" => 39,
|
||||||
|
"DeepSkyBlue2" => 38,
|
||||||
|
"DeepSkyBlue3" => 31,
|
||||||
|
"DeepSkyBlue4" => 32,
|
||||||
|
"DeepSkyBlue5" => 23,
|
||||||
|
"DeepSkyBlue6" => 24,
|
||||||
|
"DeepSkyBlue7" => 25,
|
||||||
|
"DodgerBlue1" => 33,
|
||||||
|
"DodgerBlue2" => 27,
|
||||||
|
"DodgerBlue3" => 26,
|
||||||
|
"Fuchsia" => 13,
|
||||||
|
"Gold1" => 220,
|
||||||
|
"Gold2" => 142,
|
||||||
|
"Gold3" => 178,
|
||||||
|
"Green" => 2,
|
||||||
|
"Green1" => 46,
|
||||||
|
"Green2" => 34,
|
||||||
|
"Green3" => 40,
|
||||||
|
"Green4" => 28,
|
||||||
|
"GreenYellow" => 154,
|
||||||
|
"Grey" => 8,
|
||||||
|
"Grey0" => 16,
|
||||||
|
"Grey100" => 231,
|
||||||
|
"Grey11" => 234,
|
||||||
|
"Grey15" => 235,
|
||||||
|
"Grey19" => 236,
|
||||||
|
"Grey23" => 237,
|
||||||
|
"Grey27" => 238,
|
||||||
|
"Grey3" => 232,
|
||||||
|
"Grey30" => 239,
|
||||||
|
"Grey35" => 240,
|
||||||
|
"Grey37" => 59,
|
||||||
|
"Grey39" => 241,
|
||||||
|
"Grey42" => 242,
|
||||||
|
"Grey46" => 243,
|
||||||
|
"Grey50" => 244,
|
||||||
|
"Grey53" => 102,
|
||||||
|
"Grey54" => 245,
|
||||||
|
"Grey58" => 246,
|
||||||
|
"Grey62" => 247,
|
||||||
|
"Grey63" => 139,
|
||||||
|
"Grey66" => 248,
|
||||||
|
"Grey69" => 145,
|
||||||
|
"Grey7" => 233,
|
||||||
|
"Grey70" => 249,
|
||||||
|
"Grey74" => 250,
|
||||||
|
"Grey78" => 251,
|
||||||
|
"Grey82" => 252,
|
||||||
|
"Grey84" => 188,
|
||||||
|
"Grey85" => 253,
|
||||||
|
"Grey89" => 254,
|
||||||
|
"Grey93" => 255,
|
||||||
|
"Honeydew2" => 194,
|
||||||
|
"HotPink" => 205,
|
||||||
|
"HotPink1" => 206,
|
||||||
|
"HotPink2" => 169,
|
||||||
|
"HotPink3" => 132,
|
||||||
|
"HotPink4" => 168,
|
||||||
|
"IndianRed" => 131,
|
||||||
|
"IndianRed1" => 167,
|
||||||
|
"IndianRed2" => 204,
|
||||||
|
"IndianRed3" => 203,
|
||||||
|
"Khaki1" => 228,
|
||||||
|
"Khaki3" => 185,
|
||||||
|
"LightCoral" => 210,
|
||||||
|
"LightCyan2" => 195,
|
||||||
|
"LightCyan3" => 152,
|
||||||
|
"LightGoldenrod1" => 227,
|
||||||
|
"LightGoldenrod2" => 222,
|
||||||
|
"LightGoldenrod3" => 179,
|
||||||
|
"LightGoldenrod4" => 221,
|
||||||
|
"LightGoldenrod5" => 186,
|
||||||
|
"LightGreen" => 119,
|
||||||
|
"LightGreen1" => 120,
|
||||||
|
"LightPink1" => 217,
|
||||||
|
"LightPink2" => 174,
|
||||||
|
"LightPink3" => 95,
|
||||||
|
"LightSalmon1" => 216,
|
||||||
|
"LightSalmon2" => 137,
|
||||||
|
"LightSalmon3" => 173,
|
||||||
|
"LightSeaGreen" => 37,
|
||||||
|
"LightSkyBlue1" => 153,
|
||||||
|
"LightSkyBlue2" => 109,
|
||||||
|
"LightSkyBlue3" => 110,
|
||||||
|
"LightSlateBlue" => 105,
|
||||||
|
"LightSlateGrey" => 103,
|
||||||
|
"LightSteelBlue" => 147,
|
||||||
|
"LightSteelBlue1" => 189,
|
||||||
|
"LightSteelBlue3" => 146,
|
||||||
|
"LightYellow3" => 187,
|
||||||
|
"Lime" => 10,
|
||||||
|
"Magenta1" => 201,
|
||||||
|
"Magenta2" => 165,
|
||||||
|
"Magenta3" => 200,
|
||||||
|
"Magenta4" => 127,
|
||||||
|
"Magenta5" => 163,
|
||||||
|
"Magenta6" => 164,
|
||||||
|
"Maroon" => 1,
|
||||||
|
"MediumOrchid" => 134,
|
||||||
|
"MediumOrchid1" => 171,
|
||||||
|
"MediumOrchid2" => 207,
|
||||||
|
"MediumOrchid3" => 133,
|
||||||
|
"MediumPurple" => 104,
|
||||||
|
"MediumPurple1" => 141,
|
||||||
|
"MediumPurple2" => 135,
|
||||||
|
"MediumPurple3" => 140,
|
||||||
|
"MediumPurple4" => 97,
|
||||||
|
"MediumPurple5" => 98,
|
||||||
|
"MediumPurple6" => 60,
|
||||||
|
"MediumSpringGreen" => 49,
|
||||||
|
"MediumTurquoise" => 80,
|
||||||
|
"MediumVioletRed" => 126,
|
||||||
|
"MistyRose1" => 224,
|
||||||
|
"MistyRose3" => 181,
|
||||||
|
"NavajoWhite1" => 223,
|
||||||
|
"NavajoWhite3" => 144,
|
||||||
|
"Navy" => 4,
|
||||||
|
"NavyBlue" => 17,
|
||||||
|
"Olive" => 3,
|
||||||
|
"Orange1" => 214,
|
||||||
|
"Orange2" => 172,
|
||||||
|
"Orange3" => 58,
|
||||||
|
"Orange4" => 94,
|
||||||
|
"OrangeRed1" => 202,
|
||||||
|
"Orchid" => 170,
|
||||||
|
"Orchid1" => 213,
|
||||||
|
"Orchid2" => 212,
|
||||||
|
"PaleGreen1" => 121,
|
||||||
|
"PaleGreen2" => 156,
|
||||||
|
"PaleGreen3" => 114,
|
||||||
|
"PaleGreen4" => 77,
|
||||||
|
"PaleTurquoise1" => 159,
|
||||||
|
"PaleTurquoise4" => 66,
|
||||||
|
"PaleVioletRed1" => 211,
|
||||||
|
"Pink1" => 218,
|
||||||
|
"Pink3" => 175,
|
||||||
|
"Plum1" => 219,
|
||||||
|
"Plum2" => 183,
|
||||||
|
"Plum3" => 176,
|
||||||
|
"Plum4" => 96,
|
||||||
|
"Purple" => 129,
|
||||||
|
"Purple1" => 5,
|
||||||
|
"Purple2" => 93,
|
||||||
|
"Purple3" => 56,
|
||||||
|
"Purple4" => 54,
|
||||||
|
"Purple5" => 55,
|
||||||
|
"Red" => 9,
|
||||||
|
"Red1" => 196,
|
||||||
|
"Red2" => 124,
|
||||||
|
"Red3" => 160,
|
||||||
|
"RosyBrown" => 138,
|
||||||
|
"RoyalBlue1" => 63,
|
||||||
|
"Salmon1" => 209,
|
||||||
|
"SandyBrown" => 215,
|
||||||
|
"SeaGreen1" => 84,
|
||||||
|
"SeaGreen2" => 85,
|
||||||
|
"SeaGreen3" => 83,
|
||||||
|
"SeaGreen4" => 78,
|
||||||
|
"Silver" => 7,
|
||||||
|
"SkyBlue1" => 117,
|
||||||
|
"SkyBlue2" => 111,
|
||||||
|
"SkyBlue3" => 74,
|
||||||
|
"SlateBlue1" => 99,
|
||||||
|
"SlateBlue2" => 61,
|
||||||
|
"SlateBlue3" => 62,
|
||||||
|
"SpringGreen1" => 48,
|
||||||
|
"SpringGreen2" => 42,
|
||||||
|
"SpringGreen3" => 47,
|
||||||
|
"SpringGreen4" => 35,
|
||||||
|
"SpringGreen5" => 41,
|
||||||
|
"SpringGreen6" => 29,
|
||||||
|
"SteelBlue" => 67,
|
||||||
|
"SteelBlue1" => 75,
|
||||||
|
"SteelBlue2" => 81,
|
||||||
|
"SteelBlue3" => 68,
|
||||||
|
"Tan" => 180,
|
||||||
|
"Teal" => 6,
|
||||||
|
"Thistle1" => 225,
|
||||||
|
"Thistle3" => 182,
|
||||||
|
"Turquoise2" => 45,
|
||||||
|
"Turquoise4" => 30,
|
||||||
|
"Violet" => 177,
|
||||||
|
"Wheat1" => 229,
|
||||||
|
"Wheat4" => 101,
|
||||||
|
"White" => 15,
|
||||||
|
"Yellow" => 11,
|
||||||
|
"Yellow1" => 226,
|
||||||
|
"Yellow2" => 190,
|
||||||
|
"Yellow3" => 184,
|
||||||
|
"Yellow4" => 100,
|
||||||
|
"Yellow5" => 106,
|
||||||
|
"Yellow6" => 148,
|
||||||
|
s if s.starts_with("#")
|
||||||
|
&& s.len() == 7
|
||||||
|
&& s[1..].as_bytes().iter().all(|&b| {
|
||||||
|
(b >= b'0' && b <= b'9')
|
||||||
|
|| (b >= b'a' && b <= b'f')
|
||||||
|
|| (b >= b'A' && b <= b'F')
|
||||||
|
}) =>
|
||||||
|
{
|
||||||
|
return Ok(Color::Rgb(
|
||||||
|
u8::from_str_radix(&s[1..3], 16)
|
||||||
|
.map_err(|_| de::Error::custom("invalid `color` value"))?,
|
||||||
|
u8::from_str_radix(&s[3..5], 16)
|
||||||
|
.map_err(|_| de::Error::custom("invalid `color` value"))?,
|
||||||
|
u8::from_str_radix(&s[5..7], 16)
|
||||||
|
.map_err(|_| de::Error::custom("invalid `color` value"))?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
s if s.starts_with("#")
|
||||||
|
&& s.len() == 4
|
||||||
|
&& s[1..].as_bytes().iter().all(|&b| {
|
||||||
|
(b >= b'0' && b <= b'9')
|
||||||
|
|| (b >= b'a' && b <= b'f')
|
||||||
|
|| (b >= b'A' && b <= b'F')
|
||||||
|
}) =>
|
||||||
|
{
|
||||||
|
return Ok(Color::Rgb(
|
||||||
|
17 * u8::from_str_radix(&s[1..2], 16)
|
||||||
|
.map_err(|_| de::Error::custom("invalid `color` value"))?,
|
||||||
|
17 * u8::from_str_radix(&s[2..3], 16)
|
||||||
|
.map_err(|_| de::Error::custom("invalid `color` value"))?,
|
||||||
|
17 * u8::from_str_radix(&s[3..4], 16)
|
||||||
|
.map_err(|_| de::Error::custom("invalid `color` value"))?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
_ => return Err(de::Error::custom("invalid `color` value")),
|
||||||
|
};
|
||||||
|
return Ok(Color::Byte(byte));
|
||||||
|
}
|
||||||
|
Err(de::Error::custom("invalid `color` value"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_color_de() {
|
||||||
|
#[derive(Debug, Deserialize, PartialEq)]
|
||||||
|
struct V {
|
||||||
|
k: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! test_color {
|
||||||
|
($s:literal, ok $v:expr) => {
|
||||||
|
assert_eq!(
|
||||||
|
toml::from_str::<V>(std::concat!("k = \"", $s, "\"")),
|
||||||
|
Ok(V { k: $v })
|
||||||
|
);
|
||||||
|
};
|
||||||
|
($s:literal, err $v:literal) => {
|
||||||
|
assert_eq!(
|
||||||
|
toml::from_str::<V>(std::concat!("k = \"", $s, "\""))
|
||||||
|
.unwrap_err()
|
||||||
|
.to_string(),
|
||||||
|
$v.to_string()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
test_color!("#Ff6600", ok Color::Rgb(255, 102, 0));
|
||||||
|
test_color!("#f60", ok Color::Rgb(255, 102, 0));
|
||||||
|
test_color!("#gb0", err "invalid `color` value for key `k` at line 1 column 1");
|
||||||
|
test_color!("Olive", ok Color::Byte(3));
|
||||||
|
test_color!("Oafahifdave", err "invalid `color` value for key `k` at line 1 column 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Color {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Color::Black | Color::Byte(0) => serializer.serialize_str("Black"),
|
||||||
|
Color::Byte(1) => serializer.serialize_str("Maroon"),
|
||||||
|
Color::Green | Color::Byte(2) => serializer.serialize_str("Green"),
|
||||||
|
Color::Byte(3) => serializer.serialize_str("Olive"),
|
||||||
|
Color::Byte(4) => serializer.serialize_str("Navy"),
|
||||||
|
Color::Byte(5) => serializer.serialize_str("Purple"),
|
||||||
|
Color::Byte(6) => serializer.serialize_str("Teal"),
|
||||||
|
Color::Byte(7) => serializer.serialize_str("Silver"),
|
||||||
|
Color::Byte(8) => serializer.serialize_str("Grey"),
|
||||||
|
Color::Red | Color::Byte(9) => serializer.serialize_str("Red"),
|
||||||
|
Color::Byte(10) => serializer.serialize_str("Lime"),
|
||||||
|
Color::Yellow | Color::Byte(11) => serializer.serialize_str("Yellow"),
|
||||||
|
Color::Blue | Color::Byte(12) => serializer.serialize_str("Blue"),
|
||||||
|
Color::Byte(13) => serializer.serialize_str("Fuchsia"),
|
||||||
|
Color::Byte(14) => serializer.serialize_str("Aqua"),
|
||||||
|
Color::White | Color::Byte(15) => serializer.serialize_str("White"),
|
||||||
|
Color::Byte(16) => serializer.serialize_str("Grey0"),
|
||||||
|
Color::Byte(17) => serializer.serialize_str("NavyBlue"),
|
||||||
|
Color::Byte(18) => serializer.serialize_str("DarkBlue"),
|
||||||
|
Color::Byte(19) => serializer.serialize_str("Blue3"),
|
||||||
|
Color::Byte(20) => serializer.serialize_str("Blue3"),
|
||||||
|
Color::Byte(21) => serializer.serialize_str("Blue1"),
|
||||||
|
Color::Byte(22) => serializer.serialize_str("DarkGreen"),
|
||||||
|
Color::Byte(23) => serializer.serialize_str("DeepSkyBlue4"),
|
||||||
|
Color::Byte(24) => serializer.serialize_str("DeepSkyBlue4"),
|
||||||
|
Color::Byte(25) => serializer.serialize_str("DeepSkyBlue4"),
|
||||||
|
Color::Byte(26) => serializer.serialize_str("DodgerBlue3"),
|
||||||
|
Color::Byte(27) => serializer.serialize_str("DodgerBlue2"),
|
||||||
|
Color::Byte(28) => serializer.serialize_str("Green4"),
|
||||||
|
Color::Byte(29) => serializer.serialize_str("SpringGreen4"),
|
||||||
|
Color::Byte(30) => serializer.serialize_str("Turquoise4"),
|
||||||
|
Color::Byte(31) => serializer.serialize_str("DeepSkyBlue3"),
|
||||||
|
Color::Byte(32) => serializer.serialize_str("DeepSkyBlue3"),
|
||||||
|
Color::Byte(33) => serializer.serialize_str("DodgerBlue1"),
|
||||||
|
Color::Byte(34) => serializer.serialize_str("Green3"),
|
||||||
|
Color::Byte(35) => serializer.serialize_str("SpringGreen3"),
|
||||||
|
Color::Byte(36) => serializer.serialize_str("DarkCyan"),
|
||||||
|
Color::Byte(37) => serializer.serialize_str("LightSeaGreen"),
|
||||||
|
Color::Byte(38) => serializer.serialize_str("DeepSkyBlue2"),
|
||||||
|
Color::Byte(39) => serializer.serialize_str("DeepSkyBlue1"),
|
||||||
|
Color::Byte(40) => serializer.serialize_str("Green3"),
|
||||||
|
Color::Byte(41) => serializer.serialize_str("SpringGreen3"),
|
||||||
|
Color::Byte(42) => serializer.serialize_str("SpringGreen2"),
|
||||||
|
Color::Byte(43) => serializer.serialize_str("Cyan3"),
|
||||||
|
Color::Byte(44) => serializer.serialize_str("DarkTurquoise"),
|
||||||
|
Color::Byte(45) => serializer.serialize_str("Turquoise2"),
|
||||||
|
Color::Byte(46) => serializer.serialize_str("Green1"),
|
||||||
|
Color::Byte(47) => serializer.serialize_str("SpringGreen2"),
|
||||||
|
Color::Byte(48) => serializer.serialize_str("SpringGreen1"),
|
||||||
|
Color::Byte(49) => serializer.serialize_str("MediumSpringGreen"),
|
||||||
|
Color::Byte(50) => serializer.serialize_str("Cyan2"),
|
||||||
|
Color::Byte(51) => serializer.serialize_str("Cyan1"),
|
||||||
|
Color::Byte(52) => serializer.serialize_str("DarkRed"),
|
||||||
|
Color::Byte(53) => serializer.serialize_str("DeepPink4"),
|
||||||
|
Color::Byte(54) => serializer.serialize_str("Purple4"),
|
||||||
|
Color::Byte(55) => serializer.serialize_str("Purple4"),
|
||||||
|
Color::Byte(56) => serializer.serialize_str("Purple3"),
|
||||||
|
Color::Byte(57) => serializer.serialize_str("BlueViolet"),
|
||||||
|
Color::Byte(58) => serializer.serialize_str("Orange4"),
|
||||||
|
Color::Byte(59) => serializer.serialize_str("Grey37"),
|
||||||
|
Color::Byte(60) => serializer.serialize_str("MediumPurple4"),
|
||||||
|
Color::Byte(61) => serializer.serialize_str("SlateBlue3"),
|
||||||
|
Color::Byte(62) => serializer.serialize_str("SlateBlue3"),
|
||||||
|
Color::Byte(63) => serializer.serialize_str("RoyalBlue1"),
|
||||||
|
Color::Byte(64) => serializer.serialize_str("Chartreuse4"),
|
||||||
|
Color::Byte(65) => serializer.serialize_str("DarkSeaGreen4"),
|
||||||
|
Color::Byte(66) => serializer.serialize_str("PaleTurquoise4"),
|
||||||
|
Color::Byte(67) => serializer.serialize_str("SteelBlue"),
|
||||||
|
Color::Byte(68) => serializer.serialize_str("SteelBlue3"),
|
||||||
|
Color::Byte(69) => serializer.serialize_str("CornflowerBlue"),
|
||||||
|
Color::Byte(70) => serializer.serialize_str("Chartreuse3"),
|
||||||
|
Color::Byte(71) => serializer.serialize_str("DarkSeaGreen4"),
|
||||||
|
Color::Byte(72) => serializer.serialize_str("CadetBlue"),
|
||||||
|
Color::Byte(73) => serializer.serialize_str("CadetBlue"),
|
||||||
|
Color::Byte(74) => serializer.serialize_str("SkyBlue3"),
|
||||||
|
Color::Byte(75) => serializer.serialize_str("SteelBlue1"),
|
||||||
|
Color::Byte(76) => serializer.serialize_str("Chartreuse3"),
|
||||||
|
Color::Byte(77) => serializer.serialize_str("PaleGreen3"),
|
||||||
|
Color::Byte(78) => serializer.serialize_str("SeaGreen3"),
|
||||||
|
Color::Byte(79) => serializer.serialize_str("Aquamarine3"),
|
||||||
|
Color::Byte(80) => serializer.serialize_str("MediumTurquoise"),
|
||||||
|
Color::Byte(81) => serializer.serialize_str("SteelBlue1"),
|
||||||
|
Color::Byte(82) => serializer.serialize_str("Chartreuse2"),
|
||||||
|
Color::Byte(83) => serializer.serialize_str("SeaGreen2"),
|
||||||
|
Color::Byte(84) => serializer.serialize_str("SeaGreen1"),
|
||||||
|
Color::Byte(85) => serializer.serialize_str("SeaGreen1"),
|
||||||
|
Color::Byte(86) => serializer.serialize_str("Aquamarine1"),
|
||||||
|
Color::Byte(87) => serializer.serialize_str("DarkSlateGray2"),
|
||||||
|
Color::Byte(88) => serializer.serialize_str("DarkRed"),
|
||||||
|
Color::Byte(89) => serializer.serialize_str("DeepPink4"),
|
||||||
|
Color::Byte(90) => serializer.serialize_str("DarkMagenta"),
|
||||||
|
Color::Byte(91) => serializer.serialize_str("DarkMagenta"),
|
||||||
|
Color::Byte(92) => serializer.serialize_str("DarkViolet"),
|
||||||
|
Color::Byte(93) => serializer.serialize_str("Purple"),
|
||||||
|
Color::Byte(94) => serializer.serialize_str("Orange4"),
|
||||||
|
Color::Byte(95) => serializer.serialize_str("LightPink4"),
|
||||||
|
Color::Byte(96) => serializer.serialize_str("Plum4"),
|
||||||
|
Color::Byte(97) => serializer.serialize_str("MediumPurple3"),
|
||||||
|
Color::Byte(98) => serializer.serialize_str("MediumPurple3"),
|
||||||
|
Color::Byte(99) => serializer.serialize_str("SlateBlue1"),
|
||||||
|
Color::Byte(100) => serializer.serialize_str("Yellow4"),
|
||||||
|
Color::Byte(101) => serializer.serialize_str("Wheat4"),
|
||||||
|
Color::Byte(102) => serializer.serialize_str("Grey53"),
|
||||||
|
Color::Byte(103) => serializer.serialize_str("LightSlateGrey"),
|
||||||
|
Color::Byte(104) => serializer.serialize_str("MediumPurple"),
|
||||||
|
Color::Byte(105) => serializer.serialize_str("LightSlateBlue"),
|
||||||
|
Color::Byte(106) => serializer.serialize_str("Yellow4"),
|
||||||
|
Color::Byte(107) => serializer.serialize_str("DarkOliveGreen3"),
|
||||||
|
Color::Byte(108) => serializer.serialize_str("DarkSeaGreen"),
|
||||||
|
Color::Byte(109) => serializer.serialize_str("LightSkyBlue3"),
|
||||||
|
Color::Byte(110) => serializer.serialize_str("LightSkyBlue3"),
|
||||||
|
Color::Byte(111) => serializer.serialize_str("SkyBlue2"),
|
||||||
|
Color::Byte(112) => serializer.serialize_str("Chartreuse2"),
|
||||||
|
Color::Byte(113) => serializer.serialize_str("DarkOliveGreen3"),
|
||||||
|
Color::Byte(114) => serializer.serialize_str("PaleGreen3"),
|
||||||
|
Color::Byte(115) => serializer.serialize_str("DarkSeaGreen3"),
|
||||||
|
Color::Byte(116) => serializer.serialize_str("DarkSlateGray3"),
|
||||||
|
Color::Byte(117) => serializer.serialize_str("SkyBlue1"),
|
||||||
|
Color::Byte(118) => serializer.serialize_str("Chartreuse1"),
|
||||||
|
Color::Byte(119) => serializer.serialize_str("LightGreen"),
|
||||||
|
Color::Byte(120) => serializer.serialize_str("LightGreen"),
|
||||||
|
Color::Byte(121) => serializer.serialize_str("PaleGreen1"),
|
||||||
|
Color::Byte(122) => serializer.serialize_str("Aquamarine1"),
|
||||||
|
Color::Byte(123) => serializer.serialize_str("DarkSlateGray1"),
|
||||||
|
Color::Byte(124) => serializer.serialize_str("Red3"),
|
||||||
|
Color::Byte(125) => serializer.serialize_str("DeepPink4"),
|
||||||
|
Color::Byte(126) => serializer.serialize_str("MediumVioletRed"),
|
||||||
|
Color::Byte(127) => serializer.serialize_str("Magenta3"),
|
||||||
|
Color::Byte(128) => serializer.serialize_str("DarkViolet"),
|
||||||
|
Color::Byte(129) => serializer.serialize_str("Purple"),
|
||||||
|
Color::Byte(130) => serializer.serialize_str("DarkOrange3"),
|
||||||
|
Color::Byte(131) => serializer.serialize_str("IndianRed"),
|
||||||
|
Color::Byte(132) => serializer.serialize_str("HotPink3"),
|
||||||
|
Color::Byte(133) => serializer.serialize_str("MediumOrchid3"),
|
||||||
|
Color::Byte(134) => serializer.serialize_str("MediumOrchid"),
|
||||||
|
Color::Byte(135) => serializer.serialize_str("MediumPurple2"),
|
||||||
|
Color::Byte(136) => serializer.serialize_str("DarkGoldenrod"),
|
||||||
|
Color::Byte(137) => serializer.serialize_str("LightSalmon3"),
|
||||||
|
Color::Byte(138) => serializer.serialize_str("RosyBrown"),
|
||||||
|
Color::Byte(139) => serializer.serialize_str("Grey63"),
|
||||||
|
Color::Byte(140) => serializer.serialize_str("MediumPurple2"),
|
||||||
|
Color::Byte(141) => serializer.serialize_str("MediumPurple1"),
|
||||||
|
Color::Byte(142) => serializer.serialize_str("Gold3"),
|
||||||
|
Color::Byte(143) => serializer.serialize_str("DarkKhaki"),
|
||||||
|
Color::Byte(144) => serializer.serialize_str("NavajoWhite3"),
|
||||||
|
Color::Byte(145) => serializer.serialize_str("Grey69"),
|
||||||
|
Color::Byte(146) => serializer.serialize_str("LightSteelBlue3"),
|
||||||
|
Color::Byte(147) => serializer.serialize_str("LightSteelBlue"),
|
||||||
|
Color::Byte(148) => serializer.serialize_str("Yellow3"),
|
||||||
|
Color::Byte(149) => serializer.serialize_str("DarkOliveGreen3"),
|
||||||
|
Color::Byte(150) => serializer.serialize_str("DarkSeaGreen3"),
|
||||||
|
Color::Byte(151) => serializer.serialize_str("DarkSeaGreen2"),
|
||||||
|
Color::Byte(152) => serializer.serialize_str("LightCyan3"),
|
||||||
|
Color::Byte(153) => serializer.serialize_str("LightSkyBlue1"),
|
||||||
|
Color::Byte(154) => serializer.serialize_str("GreenYellow"),
|
||||||
|
Color::Byte(155) => serializer.serialize_str("DarkOliveGreen2"),
|
||||||
|
Color::Byte(156) => serializer.serialize_str("PaleGreen1"),
|
||||||
|
Color::Byte(157) => serializer.serialize_str("DarkSeaGreen2"),
|
||||||
|
Color::Byte(158) => serializer.serialize_str("DarkSeaGreen1"),
|
||||||
|
Color::Byte(159) => serializer.serialize_str("PaleTurquoise1"),
|
||||||
|
Color::Byte(160) => serializer.serialize_str("Red3"),
|
||||||
|
Color::Byte(161) => serializer.serialize_str("DeepPink3"),
|
||||||
|
Color::Byte(162) => serializer.serialize_str("DeepPink3"),
|
||||||
|
Color::Byte(163) => serializer.serialize_str("Magenta3"),
|
||||||
|
Color::Byte(164) => serializer.serialize_str("Magenta3"),
|
||||||
|
Color::Byte(165) => serializer.serialize_str("Magenta2"),
|
||||||
|
Color::Byte(166) => serializer.serialize_str("DarkOrange3"),
|
||||||
|
Color::Byte(167) => serializer.serialize_str("IndianRed"),
|
||||||
|
Color::Byte(168) => serializer.serialize_str("HotPink3"),
|
||||||
|
Color::Byte(169) => serializer.serialize_str("HotPink2"),
|
||||||
|
Color::Byte(170) => serializer.serialize_str("Orchid"),
|
||||||
|
Color::Byte(171) => serializer.serialize_str("MediumOrchid1"),
|
||||||
|
Color::Byte(172) => serializer.serialize_str("Orange3"),
|
||||||
|
Color::Byte(173) => serializer.serialize_str("LightSalmon3"),
|
||||||
|
Color::Byte(174) => serializer.serialize_str("LightPink3"),
|
||||||
|
Color::Byte(175) => serializer.serialize_str("Pink3"),
|
||||||
|
Color::Byte(176) => serializer.serialize_str("Plum3"),
|
||||||
|
Color::Byte(177) => serializer.serialize_str("Violet"),
|
||||||
|
Color::Byte(178) => serializer.serialize_str("Gold3"),
|
||||||
|
Color::Byte(179) => serializer.serialize_str("LightGoldenrod3"),
|
||||||
|
Color::Byte(180) => serializer.serialize_str("Tan"),
|
||||||
|
Color::Byte(181) => serializer.serialize_str("MistyRose3"),
|
||||||
|
Color::Byte(182) => serializer.serialize_str("Thistle3"),
|
||||||
|
Color::Byte(183) => serializer.serialize_str("Plum2"),
|
||||||
|
Color::Byte(184) => serializer.serialize_str("Yellow3"),
|
||||||
|
Color::Byte(185) => serializer.serialize_str("Khaki3"),
|
||||||
|
Color::Byte(186) => serializer.serialize_str("LightGoldenrod2"),
|
||||||
|
Color::Byte(187) => serializer.serialize_str("LightYellow3"),
|
||||||
|
Color::Byte(188) => serializer.serialize_str("Grey84"),
|
||||||
|
Color::Byte(189) => serializer.serialize_str("LightSteelBlue1"),
|
||||||
|
Color::Byte(190) => serializer.serialize_str("Yellow2"),
|
||||||
|
Color::Byte(191) => serializer.serialize_str("DarkOliveGreen1"),
|
||||||
|
Color::Byte(192) => serializer.serialize_str("DarkOliveGreen1"),
|
||||||
|
Color::Byte(193) => serializer.serialize_str("DarkSeaGreen1"),
|
||||||
|
Color::Byte(194) => serializer.serialize_str("Honeydew2"),
|
||||||
|
Color::Byte(195) => serializer.serialize_str("LightCyan1"),
|
||||||
|
Color::Byte(196) => serializer.serialize_str("Red1"),
|
||||||
|
Color::Byte(197) => serializer.serialize_str("DeepPink2"),
|
||||||
|
Color::Byte(198) => serializer.serialize_str("DeepPink1"),
|
||||||
|
Color::Byte(199) => serializer.serialize_str("DeepPink1"),
|
||||||
|
Color::Byte(200) => serializer.serialize_str("Magenta2"),
|
||||||
|
Color::Byte(201) => serializer.serialize_str("Magenta1"),
|
||||||
|
Color::Byte(202) => serializer.serialize_str("OrangeRed1"),
|
||||||
|
Color::Byte(203) => serializer.serialize_str("IndianRed1"),
|
||||||
|
Color::Byte(204) => serializer.serialize_str("IndianRed1"),
|
||||||
|
Color::Byte(205) => serializer.serialize_str("HotPink"),
|
||||||
|
Color::Byte(206) => serializer.serialize_str("HotPink"),
|
||||||
|
Color::Byte(207) => serializer.serialize_str("MediumOrchid1"),
|
||||||
|
Color::Byte(208) => serializer.serialize_str("DarkOrange"),
|
||||||
|
Color::Byte(209) => serializer.serialize_str("Salmon1"),
|
||||||
|
Color::Byte(210) => serializer.serialize_str("LightCoral"),
|
||||||
|
Color::Byte(211) => serializer.serialize_str("PaleVioletRed1"),
|
||||||
|
Color::Byte(212) => serializer.serialize_str("Orchid2"),
|
||||||
|
Color::Byte(213) => serializer.serialize_str("Orchid1"),
|
||||||
|
Color::Byte(214) => serializer.serialize_str("Orange1"),
|
||||||
|
Color::Byte(215) => serializer.serialize_str("SandyBrown"),
|
||||||
|
Color::Byte(216) => serializer.serialize_str("LightSalmon1"),
|
||||||
|
Color::Byte(217) => serializer.serialize_str("LightPink1"),
|
||||||
|
Color::Byte(218) => serializer.serialize_str("Pink1"),
|
||||||
|
Color::Byte(219) => serializer.serialize_str("Plum1"),
|
||||||
|
Color::Byte(220) => serializer.serialize_str("Gold1"),
|
||||||
|
Color::Byte(221) => serializer.serialize_str("LightGoldenrod2"),
|
||||||
|
Color::Byte(222) => serializer.serialize_str("LightGoldenrod2"),
|
||||||
|
Color::Byte(223) => serializer.serialize_str("NavajoWhite1"),
|
||||||
|
Color::Byte(224) => serializer.serialize_str("MistyRose1"),
|
||||||
|
Color::Byte(225) => serializer.serialize_str("Thistle1"),
|
||||||
|
Color::Byte(226) => serializer.serialize_str("Yellow1"),
|
||||||
|
Color::Byte(227) => serializer.serialize_str("LightGoldenrod1"),
|
||||||
|
Color::Byte(228) => serializer.serialize_str("Khaki1"),
|
||||||
|
Color::Byte(229) => serializer.serialize_str("Wheat1"),
|
||||||
|
Color::Byte(230) => serializer.serialize_str("Cornsilk1"),
|
||||||
|
Color::Byte(231) => serializer.serialize_str("Grey100"),
|
||||||
|
Color::Byte(232) => serializer.serialize_str("Grey3"),
|
||||||
|
Color::Byte(233) => serializer.serialize_str("Grey7"),
|
||||||
|
Color::Byte(234) => serializer.serialize_str("Grey11"),
|
||||||
|
Color::Byte(235) => serializer.serialize_str("Grey15"),
|
||||||
|
Color::Byte(236) => serializer.serialize_str("Grey19"),
|
||||||
|
Color::Byte(237) => serializer.serialize_str("Grey23"),
|
||||||
|
Color::Byte(238) => serializer.serialize_str("Grey27"),
|
||||||
|
Color::Byte(239) => serializer.serialize_str("Grey30"),
|
||||||
|
Color::Byte(240) => serializer.serialize_str("Grey35"),
|
||||||
|
Color::Byte(241) => serializer.serialize_str("Grey39"),
|
||||||
|
Color::Byte(242) => serializer.serialize_str("Grey42"),
|
||||||
|
Color::Byte(243) => serializer.serialize_str("Grey46"),
|
||||||
|
Color::Byte(244) => serializer.serialize_str("Grey50"),
|
||||||
|
Color::Byte(245) => serializer.serialize_str("Grey54"),
|
||||||
|
Color::Byte(246) => serializer.serialize_str("Grey58"),
|
||||||
|
Color::Byte(247) => serializer.serialize_str("Grey62"),
|
||||||
|
Color::Byte(248) => serializer.serialize_str("Grey66"),
|
||||||
|
Color::Byte(249) => serializer.serialize_str("Grey70"),
|
||||||
|
Color::Byte(250) => serializer.serialize_str("Grey74"),
|
||||||
|
Color::Byte(251) => serializer.serialize_str("Grey78"),
|
||||||
|
Color::Byte(252) => serializer.serialize_str("Grey82"),
|
||||||
|
Color::Byte(253) => serializer.serialize_str("Grey85"),
|
||||||
|
Color::Byte(254) => serializer.serialize_str("Grey89"),
|
||||||
|
Color::Byte(255) => serializer.serialize_str("Grey93"),
|
||||||
|
_ => serializer.serialize_str("Black"), // FIXME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The attributes of a `Cell`.
|
/// The attributes of a `Cell`.
|
||||||
///
|
///
|
||||||
/// `Attr` enumerates all combinations of attributes a given style may have.
|
/// `Attr` enumerates all combinations of attributes a given style may have.
|
||||||
|
|
Loading…
Reference in New Issue