build.rs: add proc-macro to generate Override structs for configuration
parent
1db2c16f95
commit
0169025d50
|
@ -795,6 +795,8 @@ dependencies = [
|
|||
"notify",
|
||||
"notify-rust",
|
||||
"pcre2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rmp",
|
||||
"rmp-serde",
|
||||
"rmpv",
|
||||
|
@ -806,6 +808,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"structopt",
|
||||
"svg",
|
||||
"syn",
|
||||
"termion",
|
||||
"toml",
|
||||
"unicode-segmentation",
|
||||
|
@ -1622,9 +1625,9 @@ checksum = "0b65a64d32a41db2a8081aa03c1ccca26f246ff681add693f8b01307b137da79"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.30"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2"
|
||||
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -52,6 +52,10 @@ pcre2 = { version = "0.2.3", optional = true }
|
|||
structopt = { version = "0.3.14", default-features = false }
|
||||
svg_crate = { version = "0.8.0", optional = true, package = "svg" }
|
||||
|
||||
[build-dependencies]
|
||||
syn = { version = "1.0.31", features = [] }
|
||||
quote = "^1.0"
|
||||
proc-macro2 = "1.0.18"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
14
build.rs
14
build.rs
|
@ -19,8 +19,22 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate quote;
|
||||
extern crate syn;
|
||||
mod config_macros;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
config_macros::override_derive(&[
|
||||
("src/conf/pager.rs", "PagerSettings"),
|
||||
("src/conf/listing.rs", "ListingSettings"),
|
||||
("src/conf/notifications.rs", "NotificationsSettings"),
|
||||
("src/conf/shortcuts.rs", "Shortcuts"),
|
||||
("src/conf/composing.rs", "ComposingSettings"),
|
||||
("src/conf/tags.rs", "TagsSettings"),
|
||||
("src/conf/pgp.rs", "PGPSettings"),
|
||||
]);
|
||||
#[cfg(feature = "cli-docs")]
|
||||
{
|
||||
const MANDOC_OPTS: &[&'static str] = &["-T", "utf8", "-I", "os=Generated by mandoc(1)"];
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* meli -
|
||||
*
|
||||
* Copyright Manos Pitsidianakis
|
||||
*
|
||||
* This file is part of meli.
|
||||
*
|
||||
* meli is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* meli is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
// Write ConfigStructOverride to overrides.rs
|
||||
pub fn override_derive(filenames: &[(&str, &str)]) {
|
||||
let mut output_file =
|
||||
File::create("src/conf/overrides.rs").expect("Unable to open output file");
|
||||
let mut output_string = r##"/*
|
||||
* meli - conf/overrides.rs
|
||||
*
|
||||
* Copyright 2020 Manos Pitsidianakis
|
||||
*
|
||||
* This file is part of meli.
|
||||
*
|
||||
* meli is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* meli is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//! This module is automatically generated by build.rs.
|
||||
use super::*;
|
||||
|
||||
"##
|
||||
.to_string();
|
||||
|
||||
'file_loop: for (filename, ident) in filenames {
|
||||
println!("cargo:rerun-if-changed={}", filename);
|
||||
let mut file = File::open(&filename).expect(&format!("Unable to open file `{}`", filename));
|
||||
|
||||
let mut src = String::new();
|
||||
file.read_to_string(&mut src).expect("Unable to read file");
|
||||
|
||||
let syntax = syn::parse_file(&src).expect("Unable to parse file");
|
||||
if syntax.items.iter().any(|item| {
|
||||
if let syn::Item::Struct(s) = item {
|
||||
if s.ident.to_string().ends_with("Override") {
|
||||
println!("ident {} exists, skipping {}", ident, filename);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}) {
|
||||
continue 'file_loop;
|
||||
}
|
||||
|
||||
for item in syntax.items.iter() {
|
||||
if let syn::Item::Struct(s) = item {
|
||||
if s.ident != ident {
|
||||
continue;
|
||||
}
|
||||
if s.ident.to_string().ends_with("Override") {
|
||||
unreachable!();
|
||||
}
|
||||
let override_ident: syn::Ident = format_ident!("{}Override", s.ident);
|
||||
let mut field_tokentrees = vec![];
|
||||
let mut field_idents = vec![];
|
||||
for f in &s.fields {
|
||||
let ident = &f.ident;
|
||||
let ty = &f.ty;
|
||||
let attrs = f
|
||||
.attrs
|
||||
.iter()
|
||||
.filter_map(|f| {
|
||||
let mut new_attr = f.clone();
|
||||
if let quote::__private::TokenTree::Group(g) =
|
||||
f.tokens.clone().into_iter().next().unwrap()
|
||||
{
|
||||
let attr_inner_value = f.tokens.to_string();
|
||||
if !attr_inner_value.starts_with("( default")
|
||||
&& !attr_inner_value.starts_with("( default =")
|
||||
{
|
||||
return None;
|
||||
}
|
||||
if attr_inner_value.starts_with("( default =") {
|
||||
let rest = g.stream().clone().into_iter().skip(4);
|
||||
new_attr.tokens = quote! { ( #(#rest)*) };
|
||||
if new_attr.tokens.to_string().as_str() == "( )" {
|
||||
return None;
|
||||
}
|
||||
} else if attr_inner_value.starts_with("( default") {
|
||||
let rest = g.stream().clone().into_iter().skip(2);
|
||||
new_attr.tokens = quote! { ( #(#rest)*) };
|
||||
if new_attr.tokens.to_string().as_str() == "( )" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(new_attr)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let t = quote! {
|
||||
#(#attrs)*
|
||||
#[serde(default)]
|
||||
pub #ident : Option<#ty>
|
||||
};
|
||||
field_idents.push(ident);
|
||||
field_tokentrees.push(t);
|
||||
}
|
||||
//let fields = &s.fields;
|
||||
|
||||
let literal_struct = quote! {
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct #override_ident {
|
||||
#(#field_tokentrees),*
|
||||
}
|
||||
|
||||
|
||||
impl Default for #override_ident {
|
||||
fn default() -> Self {
|
||||
#override_ident {
|
||||
#(#field_idents: None),*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
output_string.extend(literal_struct.to_string().chars());
|
||||
output_string.push_str("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
let mut rustfmt = Command::new("rustfmt")
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("failed to execute rustfmt");
|
||||
|
||||
{
|
||||
// limited borrow of stdin
|
||||
let stdin = rustfmt
|
||||
.stdin
|
||||
.as_mut()
|
||||
.expect("failed to get rustfmt stdin");
|
||||
stdin
|
||||
.write_all(output_string.as_bytes())
|
||||
.expect("failed to write to rustfmit stdin");
|
||||
}
|
||||
|
||||
let output = rustfmt
|
||||
.wait_with_output()
|
||||
.expect("failed to wait on rustfmt child");
|
||||
if !output.stderr.is_empty() {
|
||||
panic!(format!("{}", String::from_utf8_lossy(&output.stderr)));
|
||||
}
|
||||
|
||||
output_file.write_all(&output.stdout).unwrap();
|
||||
*/
|
||||
output_file.write_all(output_string.as_bytes()).unwrap();
|
||||
}
|
44
src/conf.rs
44
src/conf.rs
|
@ -26,6 +26,12 @@ extern crate serde;
|
|||
extern crate toml;
|
||||
extern crate xdg;
|
||||
|
||||
use crate::conf::deserializers::non_empty_string;
|
||||
use crate::terminal::Color;
|
||||
use melib::search::Query;
|
||||
use std::collections::HashSet;
|
||||
mod overrides;
|
||||
pub use overrides::*;
|
||||
pub mod composing;
|
||||
pub mod notifications;
|
||||
pub mod pager;
|
||||
|
@ -46,10 +52,10 @@ pub use self::shortcuts::*;
|
|||
pub use self::tags::*;
|
||||
|
||||
use self::default_vals::*;
|
||||
use self::listing::{ListingSettings, ListingSettingsOverride};
|
||||
use self::notifications::{NotificationsSettings, NotificationsSettingsOverride};
|
||||
use self::listing::ListingSettings;
|
||||
use self::notifications::NotificationsSettings;
|
||||
use self::terminal::TerminalSettings;
|
||||
use crate::pager::{PagerSettings, PagerSettingsOverride};
|
||||
use crate::pager::PagerSettings;
|
||||
use crate::plugins::Plugin;
|
||||
use melib::conf::{AccountSettings, MailboxConf, ToggleFlag};
|
||||
use melib::error::*;
|
||||
|
@ -101,38 +107,6 @@ macro_rules! mailbox_settings {
|
|||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! override_def {
|
||||
($override_name:ident,
|
||||
$(#[$outer:meta])*
|
||||
pub struct $name:ident { $( $(#[$fouter:meta])* $fname:ident : $ft:ty),*,
|
||||
}) => {
|
||||
$(#[$outer])*
|
||||
pub struct $name {
|
||||
$(
|
||||
$(#[$fouter])*
|
||||
pub $fname : $ft
|
||||
),*
|
||||
}
|
||||
$(#[$outer])*
|
||||
pub struct $override_name {
|
||||
$(
|
||||
#[serde(default = "crate::conf::default_vals::none")]
|
||||
pub $fname : Option<$ft>
|
||||
),*
|
||||
}
|
||||
impl Default for $override_name {
|
||||
fn default() -> Self {
|
||||
$override_name {
|
||||
$(
|
||||
$fname : None
|
||||
),*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MailUIConf {
|
||||
#[serde(default)]
|
||||
|
|
|
@ -21,34 +21,30 @@
|
|||
|
||||
//! Configuration for composing email.
|
||||
use super::default_vals::{false_val, none, true_val};
|
||||
use crate::override_def;
|
||||
use std::collections::HashMap;
|
||||
|
||||
override_def!(
|
||||
ComposingSettingsOverride,
|
||||
/// Settings for writing and sending new e-mail
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ComposingSettings {
|
||||
/// A command to pipe new emails to
|
||||
/// Required
|
||||
#[serde(alias = "mailer-cmd")]
|
||||
mailer_cmd: String,
|
||||
/// Command to launch editor. Can have arguments. Draft filename is given as the last argument. If it's missing, the environment variable $EDITOR is looked up.
|
||||
#[serde(default = "none", alias = "editor-cmd")]
|
||||
editor_cmd: Option<String>,
|
||||
/// Embed editor (for terminal interfaces) instead of forking and waiting.
|
||||
#[serde(default = "false_val")]
|
||||
embed: bool,
|
||||
/// Set "format=flowed" in plain text attachments.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "format-flowed")]
|
||||
format_flowed: bool,
|
||||
/// Set default header values for new drafts
|
||||
/// Default: empty
|
||||
#[serde(default, alias = "default-header-values")]
|
||||
default_header_values: HashMap<String, String>,
|
||||
}
|
||||
);
|
||||
/// Settings for writing and sending new e-mail
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ComposingSettings {
|
||||
/// A command to pipe new emails to
|
||||
/// Required
|
||||
#[serde(alias = "mailer-cmd")]
|
||||
pub mailer_cmd: String,
|
||||
/// Command to launch editor. Can have arguments. Draft filename is given as the last argument. If it's missing, the environment variable $EDITOR is looked up.
|
||||
#[serde(default = "none", alias = "editor-cmd")]
|
||||
pub editor_cmd: Option<String>,
|
||||
/// Embed editor (for terminal interfaces) instead of forking and waiting.
|
||||
#[serde(default = "false_val")]
|
||||
pub embed: bool,
|
||||
/// Set "format=flowed" in plain text attachments.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "format-flowed")]
|
||||
pub format_flowed: bool,
|
||||
/// Set default header values for new drafts
|
||||
/// Default: empty
|
||||
#[serde(default, alias = "default-header-values")]
|
||||
pub default_header_values: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Default for ComposingSettings {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -20,38 +20,34 @@
|
|||
*/
|
||||
|
||||
use super::{default_vals::*, IndexStyle};
|
||||
use crate::override_def;
|
||||
use melib::search::Query;
|
||||
|
||||
override_def!(
|
||||
ListingSettingsOverride,
|
||||
/// Settings for mail listings
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct ListingSettings {
|
||||
/// Number of context lines when going to next page.
|
||||
/// Default: 0
|
||||
#[serde(default = "zero_val", alias = "context-lines")]
|
||||
context_lines: usize,
|
||||
/// Settings for mail listings
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct ListingSettings {
|
||||
/// Number of context lines when going to next page.
|
||||
/// Default: 0
|
||||
#[serde(default = "zero_val", alias = "context-lines")]
|
||||
pub context_lines: usize,
|
||||
|
||||
/// Datetime formatting passed verbatim to strftime(3).
|
||||
/// Default: %Y-%m-%d %T
|
||||
#[serde(default = "none", alias = "datetime-fmt")]
|
||||
datetime_fmt: Option<String>,
|
||||
/// Datetime formatting passed verbatim to strftime(3).
|
||||
/// Default: %Y-%m-%d %T
|
||||
#[serde(default = "none", alias = "datetime-fmt")]
|
||||
pub datetime_fmt: Option<String>,
|
||||
|
||||
/// Show recent dates as `X {minutes,hours,days} ago`, up to 7 days.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "recent-dates")]
|
||||
recent_dates: bool,
|
||||
/// Show recent dates as `X {minutes,hours,days} ago`, up to 7 days.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "recent-dates")]
|
||||
pub recent_dates: bool,
|
||||
|
||||
/// Show only envelopes that match this query
|
||||
/// Default: None
|
||||
#[serde(default = "none")]
|
||||
filter: Option<Query>,
|
||||
/// Show only envelopes that match this query
|
||||
/// Default: None
|
||||
#[serde(default = "none")]
|
||||
pub filter: Option<Query>,
|
||||
|
||||
#[serde(default, alias = "index-style")]
|
||||
index_style: IndexStyle,
|
||||
}
|
||||
);
|
||||
#[serde(default, alias = "index-style")]
|
||||
pub index_style: IndexStyle,
|
||||
}
|
||||
|
||||
impl Default for ListingSettings {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -20,28 +20,24 @@
|
|||
*/
|
||||
|
||||
use super::default_vals::{internal_value_false, none};
|
||||
use crate::override_def;
|
||||
|
||||
override_def!(
|
||||
NotificationsSettingsOverride,
|
||||
/// Settings for the notifications function.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct NotificationsSettings {
|
||||
/// A command to pipe notifications through
|
||||
/// Default: None
|
||||
#[serde(default = "none")]
|
||||
script: Option<String>,
|
||||
/// A file location which has its size changed when new mail arrives (max 128 bytes). Can be
|
||||
/// used to trigger new mail notifications eg with `xbiff(1)`
|
||||
/// Default: None
|
||||
#[serde(default = "none", alias = "xbiff-file-path")]
|
||||
xbiff_file_path: Option<String>,
|
||||
#[serde(default = "internal_value_false", alias = "play-sound")]
|
||||
play_sound: super::ToggleFlag,
|
||||
#[serde(default = "none", alias = "sound-file")]
|
||||
sound_file: Option<String>,
|
||||
}
|
||||
);
|
||||
/// Settings for the notifications function.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct NotificationsSettings {
|
||||
/// A command to pipe notifications through
|
||||
/// Default: None
|
||||
#[serde(default = "none")]
|
||||
pub script: Option<String>,
|
||||
/// A file location which has its size changed when new mail arrives (max 128 bytes). Can be
|
||||
/// used to trigger new mail notifications eg with `xbiff(1)`
|
||||
/// Default: None
|
||||
#[serde(default = "none", alias = "xbiff-file-path")]
|
||||
pub xbiff_file_path: Option<String>,
|
||||
#[serde(default = "internal_value_false", alias = "play-sound")]
|
||||
pub play_sound: super::ToggleFlag,
|
||||
#[serde(default = "none", alias = "sound-file")]
|
||||
pub sound_file: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for NotificationsSettings {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* meli - conf/overrides.rs
|
||||
*
|
||||
* Copyright 2020 Manos Pitsidianakis
|
||||
*
|
||||
* This file is part of meli.
|
||||
*
|
||||
* meli is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* meli is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//! This module is automatically generated by build.rs.
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct PagerSettingsOverride {
|
||||
#[doc = " Number of context lines when going to next page."]
|
||||
#[doc = " Default: 0"]
|
||||
#[serde(alias = "pager-context")]
|
||||
#[serde(default)]
|
||||
pub pager_context: Option<usize>,
|
||||
#[doc = " Stop at the end instead of displaying next mail."]
|
||||
#[doc = " Default: false"]
|
||||
#[serde(alias = "pager-stop")]
|
||||
#[serde(default)]
|
||||
pub pager_stop: Option<bool>,
|
||||
#[doc = " Always show headers when scrolling."]
|
||||
#[doc = " Default: true"]
|
||||
#[serde(alias = "headers-sticky")]
|
||||
#[serde(default)]
|
||||
pub headers_sticky: Option<bool>,
|
||||
#[doc = " The height of the pager in mail view, in percent."]
|
||||
#[doc = " Default: 80"]
|
||||
#[serde(alias = "pager-ratio")]
|
||||
#[serde(default)]
|
||||
pub pager_ratio: Option<usize>,
|
||||
#[doc = " A command to pipe mail output through for viewing in pager."]
|
||||
#[doc = " Default: None"]
|
||||
#[serde(deserialize_with = "non_empty_string")]
|
||||
#[serde(default)]
|
||||
pub filter: Option<Option<String>>,
|
||||
#[doc = " A command to pipe html output before displaying it in a pager"]
|
||||
#[doc = " Default: None"]
|
||||
#[serde(deserialize_with = "non_empty_string", alias = "html-filter")]
|
||||
#[serde(default)]
|
||||
pub html_filter: Option<Option<String>>,
|
||||
#[doc = " Respect \"format=flowed\""]
|
||||
#[doc = " Default: true"]
|
||||
#[serde(alias = "format-flowed")]
|
||||
#[serde(default)]
|
||||
pub format_flowed: Option<bool>,
|
||||
#[doc = " Split long lines that would overflow on the x axis."]
|
||||
#[doc = " Default: true"]
|
||||
#[serde(alias = "split-long-lines")]
|
||||
#[serde(default)]
|
||||
pub split_long_lines: Option<bool>,
|
||||
#[doc = " Minimum text width in columns."]
|
||||
#[doc = " Default: 80"]
|
||||
#[serde(alias = "minimum-width")]
|
||||
#[serde(default)]
|
||||
pub minimum_width: Option<usize>,
|
||||
#[doc = " Choose `text/html` alternative if `text/plain` is empty in `multipart/alternative`"]
|
||||
#[doc = " attachments."]
|
||||
#[doc = " Default: true"]
|
||||
#[serde(alias = "auto-choose-multipart-alternative")]
|
||||
#[serde(default)]
|
||||
pub auto_choose_multipart_alternative: Option<ToggleFlag>,
|
||||
}
|
||||
impl Default for PagerSettingsOverride {
|
||||
fn default() -> Self {
|
||||
PagerSettingsOverride {
|
||||
pager_context: None,
|
||||
pager_stop: None,
|
||||
headers_sticky: None,
|
||||
pager_ratio: None,
|
||||
filter: None,
|
||||
html_filter: None,
|
||||
format_flowed: None,
|
||||
split_long_lines: None,
|
||||
minimum_width: None,
|
||||
auto_choose_multipart_alternative: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ListingSettingsOverride {
|
||||
#[doc = " Number of context lines when going to next page."]
|
||||
#[doc = " Default: 0"]
|
||||
#[serde(alias = "context-lines")]
|
||||
#[serde(default)]
|
||||
pub context_lines: Option<usize>,
|
||||
#[doc = " Datetime formatting passed verbatim to strftime(3)."]
|
||||
#[doc = " Default: %Y-%m-%d %T"]
|
||||
#[serde(alias = "datetime-fmt")]
|
||||
#[serde(default)]
|
||||
pub datetime_fmt: Option<Option<String>>,
|
||||
#[doc = " Show recent dates as `X {minutes,hours,days} ago`, up to 7 days."]
|
||||
#[doc = " Default: true"]
|
||||
#[serde(alias = "recent-dates")]
|
||||
#[serde(default)]
|
||||
pub recent_dates: Option<bool>,
|
||||
#[doc = " Show only envelopes that match this query"]
|
||||
#[doc = " Default: None"]
|
||||
#[serde(default)]
|
||||
pub filter: Option<Option<Query>>,
|
||||
#[serde(alias = "index-style")]
|
||||
#[serde(default)]
|
||||
pub index_style: Option<IndexStyle>,
|
||||
}
|
||||
impl Default for ListingSettingsOverride {
|
||||
fn default() -> Self {
|
||||
ListingSettingsOverride {
|
||||
context_lines: None,
|
||||
datetime_fmt: None,
|
||||
recent_dates: None,
|
||||
filter: None,
|
||||
index_style: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct NotificationsSettingsOverride {
|
||||
#[doc = " A command to pipe notifications through"]
|
||||
#[doc = " Default: None"]
|
||||
#[serde(default)]
|
||||
pub script: Option<Option<String>>,
|
||||
#[doc = " A file location which has its size changed when new mail arrives (max 128 bytes). Can be"]
|
||||
#[doc = " used to trigger new mail notifications eg with `xbiff(1)`"]
|
||||
#[doc = " Default: None"]
|
||||
#[serde(alias = "xbiff-file-path")]
|
||||
#[serde(default)]
|
||||
pub xbiff_file_path: Option<Option<String>>,
|
||||
#[serde(alias = "play-sound")]
|
||||
#[serde(default)]
|
||||
pub play_sound: Option<super::ToggleFlag>,
|
||||
#[serde(alias = "sound-file")]
|
||||
#[serde(default)]
|
||||
pub sound_file: Option<Option<String>>,
|
||||
}
|
||||
impl Default for NotificationsSettingsOverride {
|
||||
fn default() -> Self {
|
||||
NotificationsSettingsOverride {
|
||||
script: None,
|
||||
xbiff_file_path: None,
|
||||
play_sound: None,
|
||||
sound_file: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ShortcutsOverride {
|
||||
#[serde(default)]
|
||||
pub general: Option<GeneralShortcuts>,
|
||||
#[serde(default)]
|
||||
pub listing: Option<ListingShortcuts>,
|
||||
#[serde(default)]
|
||||
pub composing: Option<ComposingShortcuts>,
|
||||
#[serde(alias = "compact-listing")]
|
||||
#[serde(default)]
|
||||
pub compact_listing: Option<CompactListingShortcuts>,
|
||||
#[serde(alias = "contact-list")]
|
||||
#[serde(default)]
|
||||
pub contact_list: Option<ContactListShortcuts>,
|
||||
#[serde(alias = "envelope-view")]
|
||||
#[serde(default)]
|
||||
pub envelope_view: Option<EnvelopeViewShortcuts>,
|
||||
#[serde(alias = "thread-view")]
|
||||
#[serde(default)]
|
||||
pub thread_view: Option<ThreadViewShortcuts>,
|
||||
#[serde(default)]
|
||||
pub pager: Option<PagerShortcuts>,
|
||||
}
|
||||
impl Default for ShortcutsOverride {
|
||||
fn default() -> Self {
|
||||
ShortcutsOverride {
|
||||
general: None,
|
||||
listing: None,
|
||||
composing: None,
|
||||
compact_listing: None,
|
||||
contact_list: None,
|
||||
envelope_view: None,
|
||||
thread_view: None,
|
||||
pager: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ComposingSettingsOverride {
|
||||
#[doc = " A command to pipe new emails to"]
|
||||
#[doc = " Required"]
|
||||
#[serde(default)]
|
||||
pub mailer_cmd: Option<String>,
|
||||
#[doc = " Command to launch editor. Can have arguments. Draft filename is given as the last argument. If it's missing, the environment variable $EDITOR is looked up."]
|
||||
#[serde(alias = "editor-cmd")]
|
||||
#[serde(default)]
|
||||
pub editor_cmd: Option<Option<String>>,
|
||||
#[doc = " Embed editor (for terminal interfaces) instead of forking and waiting."]
|
||||
#[serde(default)]
|
||||
pub embed: Option<bool>,
|
||||
#[doc = " Set \"format=flowed\" in plain text attachments."]
|
||||
#[doc = " Default: true"]
|
||||
#[serde(alias = "format-flowed")]
|
||||
#[serde(default)]
|
||||
pub format_flowed: Option<bool>,
|
||||
#[doc = " Set default header values for new drafts"]
|
||||
#[doc = " Default: empty"]
|
||||
#[serde(alias = "default-header-values")]
|
||||
#[serde(default)]
|
||||
pub default_header_values: Option<HashMap<String, String>>,
|
||||
}
|
||||
impl Default for ComposingSettingsOverride {
|
||||
fn default() -> Self {
|
||||
ComposingSettingsOverride {
|
||||
mailer_cmd: None,
|
||||
editor_cmd: None,
|
||||
embed: None,
|
||||
format_flowed: None,
|
||||
default_header_values: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct TagsSettingsOverride {
|
||||
#[serde(deserialize_with = "tag_color_de")]
|
||||
#[serde(default)]
|
||||
pub colors: Option<HashMap<u64, Color>>,
|
||||
#[serde(deserialize_with = "tag_set_de", alias = "ignore-tags")]
|
||||
#[serde(default)]
|
||||
pub ignore_tags: Option<HashSet<u64>>,
|
||||
}
|
||||
impl Default for TagsSettingsOverride {
|
||||
fn default() -> Self {
|
||||
TagsSettingsOverride {
|
||||
colors: None,
|
||||
ignore_tags: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct PGPSettingsOverride {
|
||||
#[doc = " auto verify signed e-mail according to RFC3156"]
|
||||
#[serde(alias = "auto-verify-signatures")]
|
||||
#[serde(default)]
|
||||
pub auto_verify_signatures: Option<bool>,
|
||||
#[doc = " always sign sent messages"]
|
||||
#[serde(alias = "auto-sign")]
|
||||
#[serde(default)]
|
||||
pub auto_sign: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub key: Option<Option<String>>,
|
||||
#[doc = " gpg binary name or file location to use"]
|
||||
#[serde(alias = "gpg-binary")]
|
||||
#[serde(default)]
|
||||
pub gpg_binary: Option<Option<String>>,
|
||||
}
|
||||
impl Default for PGPSettingsOverride {
|
||||
fn default() -> Self {
|
||||
PGPSettingsOverride {
|
||||
auto_verify_signatures: None,
|
||||
auto_sign: None,
|
||||
key: None,
|
||||
gpg_binary: None,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,73 +23,69 @@
|
|||
|
||||
use super::default_vals::*;
|
||||
use super::deserializers::*;
|
||||
use crate::override_def;
|
||||
use melib::ToggleFlag;
|
||||
|
||||
override_def!(
|
||||
PagerSettingsOverride,
|
||||
/// Settings for the pager function.
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct PagerSettings {
|
||||
/// Number of context lines when going to next page.
|
||||
/// Default: 0
|
||||
#[serde(default = "zero_val", alias = "pager-context")]
|
||||
pager_context: usize,
|
||||
/// Settings for the pager function.
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct PagerSettings {
|
||||
/// Number of context lines when going to next page.
|
||||
/// Default: 0
|
||||
#[serde(default = "zero_val", alias = "pager-context")]
|
||||
pub pager_context: usize,
|
||||
|
||||
/// Stop at the end instead of displaying next mail.
|
||||
/// Default: false
|
||||
#[serde(default = "false_val", alias = "pager-stop")]
|
||||
pager_stop: bool,
|
||||
/// Stop at the end instead of displaying next mail.
|
||||
/// Default: false
|
||||
#[serde(default = "false_val", alias = "pager-stop")]
|
||||
pub pager_stop: bool,
|
||||
|
||||
/// Always show headers when scrolling.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "headers-sticky")]
|
||||
headers_sticky: bool,
|
||||
/// Always show headers when scrolling.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "headers-sticky")]
|
||||
pub headers_sticky: bool,
|
||||
|
||||
/// The height of the pager in mail view, in percent.
|
||||
/// Default: 80
|
||||
#[serde(default = "eighty_val", alias = "pager-ratio")]
|
||||
pager_ratio: usize,
|
||||
/// The height of the pager in mail view, in percent.
|
||||
/// Default: 80
|
||||
#[serde(default = "eighty_val", alias = "pager-ratio")]
|
||||
pub pager_ratio: usize,
|
||||
|
||||
/// A command to pipe mail output through for viewing in pager.
|
||||
/// Default: None
|
||||
#[serde(default = "none", deserialize_with = "non_empty_string")]
|
||||
filter: Option<String>,
|
||||
/// A command to pipe mail output through for viewing in pager.
|
||||
/// Default: None
|
||||
#[serde(default = "none", deserialize_with = "non_empty_string")]
|
||||
pub filter: Option<String>,
|
||||
|
||||
/// A command to pipe html output before displaying it in a pager
|
||||
/// Default: None
|
||||
#[serde(
|
||||
default = "none",
|
||||
deserialize_with = "non_empty_string",
|
||||
alias = "html-filter"
|
||||
)]
|
||||
html_filter: Option<String>,
|
||||
/// A command to pipe html output before displaying it in a pager
|
||||
/// Default: None
|
||||
#[serde(
|
||||
default = "none",
|
||||
deserialize_with = "non_empty_string",
|
||||
alias = "html-filter"
|
||||
)]
|
||||
pub html_filter: Option<String>,
|
||||
|
||||
/// Respect "format=flowed"
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "format-flowed")]
|
||||
format_flowed: bool,
|
||||
/// Respect "format=flowed"
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "format-flowed")]
|
||||
pub format_flowed: bool,
|
||||
|
||||
/// Split long lines that would overflow on the x axis.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "split-long-lines")]
|
||||
split_long_lines: bool,
|
||||
/// Split long lines that would overflow on the x axis.
|
||||
/// Default: true
|
||||
#[serde(default = "true_val", alias = "split-long-lines")]
|
||||
pub split_long_lines: bool,
|
||||
|
||||
/// Minimum text width in columns.
|
||||
/// Default: 80
|
||||
#[serde(default = "eighty_val", alias = "minimum-width")]
|
||||
minimum_width: usize,
|
||||
/// Minimum text width in columns.
|
||||
/// Default: 80
|
||||
#[serde(default = "eighty_val", alias = "minimum-width")]
|
||||
pub minimum_width: usize,
|
||||
|
||||
/// Choose `text/html` alternative if `text/plain` is empty in `multipart/alternative`
|
||||
/// attachments.
|
||||
/// Default: true
|
||||
#[serde(
|
||||
default = "internal_value_true",
|
||||
alias = "auto-choose-multipart-alternative"
|
||||
)]
|
||||
auto_choose_multipart_alternative: ToggleFlag,
|
||||
}
|
||||
);
|
||||
/// Choose `text/html` alternative if `text/plain` is empty in `multipart/alternative`
|
||||
/// attachments.
|
||||
/// Default: true
|
||||
#[serde(
|
||||
default = "internal_value_true",
|
||||
alias = "auto-choose-multipart-alternative"
|
||||
)]
|
||||
pub auto_choose_multipart_alternative: ToggleFlag,
|
||||
}
|
||||
|
||||
impl Default for PagerSettings {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -20,30 +20,26 @@
|
|||
*/
|
||||
|
||||
use super::default_vals::*;
|
||||
use crate::override_def;
|
||||
|
||||
override_def!(
|
||||
PGPSettingsOverride,
|
||||
/// Settings for digital signing and encryption
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct PGPSettings {
|
||||
/// auto verify signed e-mail according to RFC3156
|
||||
#[serde(default = "true_val", alias = "auto-verify-signatures")]
|
||||
auto_verify_signatures: bool,
|
||||
/// Settings for digital signing and encryption
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct PGPSettings {
|
||||
/// auto verify signed e-mail according to RFC3156
|
||||
#[serde(default = "true_val", alias = "auto-verify-signatures")]
|
||||
pub auto_verify_signatures: bool,
|
||||
|
||||
/// always sign sent messages
|
||||
#[serde(default = "false_val", alias = "auto-sign")]
|
||||
auto_sign: bool,
|
||||
/// always sign sent messages
|
||||
#[serde(default = "false_val", alias = "auto-sign")]
|
||||
pub auto_sign: bool,
|
||||
|
||||
// https://tools.ietf.org/html/rfc4880#section-12.2
|
||||
#[serde(default = "none")]
|
||||
key: Option<String>,
|
||||
// https://tools.ietf.org/html/rfc4880#section-12.2
|
||||
#[serde(default = "none")]
|
||||
pub key: Option<String>,
|
||||
|
||||
/// gpg binary name or file location to use
|
||||
#[serde(default, alias = "gpg-binary")]
|
||||
gpg_binary: Option<String>,
|
||||
}
|
||||
);
|
||||
/// gpg binary name or file location to use
|
||||
#[serde(default, alias = "gpg-binary")]
|
||||
pub gpg_binary: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for PGPSettings {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::override_def;
|
||||
use crate::terminal::Key;
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -33,28 +32,25 @@ macro_rules! shortcut {
|
|||
};
|
||||
}
|
||||
|
||||
override_def!(
|
||||
ShortcutsOverride,
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Shortcuts {
|
||||
#[serde(default)]
|
||||
general: GeneralShortcuts,
|
||||
#[serde(default)]
|
||||
listing: ListingShortcuts,
|
||||
#[serde(default)]
|
||||
composing: ComposingShortcuts,
|
||||
#[serde(default, alias = "compact-listing")]
|
||||
compact_listing: CompactListingShortcuts,
|
||||
#[serde(default, alias = "contact-list")]
|
||||
contact_list: ContactListShortcuts,
|
||||
#[serde(default, alias = "envelope-view")]
|
||||
envelope_view: EnvelopeViewShortcuts,
|
||||
#[serde(default, alias = "thread-view")]
|
||||
thread_view: ThreadViewShortcuts,
|
||||
#[serde(default)]
|
||||
pager: PagerShortcuts,
|
||||
}
|
||||
);
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Shortcuts {
|
||||
#[serde(default)]
|
||||
pub general: GeneralShortcuts,
|
||||
#[serde(default)]
|
||||
pub listing: ListingShortcuts,
|
||||
#[serde(default)]
|
||||
pub composing: ComposingShortcuts,
|
||||
#[serde(default, alias = "compact-listing")]
|
||||
pub compact_listing: CompactListingShortcuts,
|
||||
#[serde(default, alias = "contact-list")]
|
||||
pub contact_list: ContactListShortcuts,
|
||||
#[serde(default, alias = "envelope-view")]
|
||||
pub envelope_view: EnvelopeViewShortcuts,
|
||||
#[serde(default, alias = "thread-view")]
|
||||
pub thread_view: ThreadViewShortcuts,
|
||||
#[serde(default)]
|
||||
pub pager: PagerShortcuts,
|
||||
}
|
||||
|
||||
impl Default for Shortcuts {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -21,22 +21,18 @@
|
|||
|
||||
//! E-mail tag configuration and {de,}serializing.
|
||||
|
||||
use crate::override_def;
|
||||
use crate::terminal::Color;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};
|
||||
use std::hash::Hasher;
|
||||
|
||||
override_def!(
|
||||
TagsSettingsOverride,
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct TagsSettings {
|
||||
#[serde(default, deserialize_with = "tag_color_de")]
|
||||
colors: HashMap<u64, Color>,
|
||||
#[serde(default, deserialize_with = "tag_set_de", alias = "ignore-tags")]
|
||||
ignore_tags: HashSet<u64>,
|
||||
}
|
||||
);
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
pub struct TagsSettings {
|
||||
#[serde(default, deserialize_with = "tag_color_de")]
|
||||
pub colors: HashMap<u64, Color>,
|
||||
#[serde(default, deserialize_with = "tag_set_de", alias = "ignore-tags")]
|
||||
pub ignore_tags: HashSet<u64>,
|
||||
}
|
||||
|
||||
impl Default for TagsSettings {
|
||||
fn default() -> Self {
|
||||
|
|
Loading…
Reference in New Issue