From 0169025d503519f5223c9d29ae0c955177a91a6b Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 20 Jun 2020 23:28:50 +0300 Subject: [PATCH] build.rs: add proc-macro to generate Override structs for configuration --- Cargo.lock | 7 +- Cargo.toml | 4 + build.rs | 14 ++ config_macros.rs | 185 +++++++++++++++++++++++++ src/conf.rs | 44 ++---- src/conf/composing.rs | 48 +++---- src/conf/listing.rs | 48 +++---- src/conf/notifications.rs | 38 +++--- src/conf/overrides.rs | 281 ++++++++++++++++++++++++++++++++++++++ src/conf/pager.rs | 108 +++++++-------- src/conf/pgp.rs | 36 +++-- src/conf/shortcuts.rs | 42 +++--- src/conf/tags.rs | 18 +-- 13 files changed, 653 insertions(+), 220 deletions(-) create mode 100644 config_macros.rs create mode 100644 src/conf/overrides.rs diff --git a/Cargo.lock b/Cargo.lock index a78ca088f..bb0cf0133 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index f26581ef6..36822e4cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/build.rs b/build.rs index c027a2714..4d2256963 100644 --- a/build.rs +++ b/build.rs @@ -19,8 +19,22 @@ * along with meli. If not, see . */ +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)"]; diff --git a/config_macros.rs b/config_macros.rs new file mode 100644 index 000000000..7ce5a0cea --- /dev/null +++ b/config_macros.rs @@ -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 . + */ + +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 . + */ + +//! 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::>(); + 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(); +} diff --git a/src/conf.rs b/src/conf.rs index 73dbfd66b..3ac3811d8 100644 --- a/src/conf.rs +++ b/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)] diff --git a/src/conf/composing.rs b/src/conf/composing.rs index 1846e4720..9dfa3d9bf 100644 --- a/src/conf/composing.rs +++ b/src/conf/composing.rs @@ -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, - /// 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, - } -); +/// 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, + /// 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, +} impl Default for ComposingSettings { fn default() -> Self { diff --git a/src/conf/listing.rs b/src/conf/listing.rs index 513342e07..d67a7291f 100644 --- a/src/conf/listing.rs +++ b/src/conf/listing.rs @@ -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, + /// Datetime formatting passed verbatim to strftime(3). + /// Default: %Y-%m-%d %T + #[serde(default = "none", alias = "datetime-fmt")] + pub datetime_fmt: Option, - /// 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, + /// Show only envelopes that match this query + /// Default: None + #[serde(default = "none")] + pub filter: Option, - #[serde(default, alias = "index-style")] - index_style: IndexStyle, - } -); + #[serde(default, alias = "index-style")] + pub index_style: IndexStyle, +} impl Default for ListingSettings { fn default() -> Self { diff --git a/src/conf/notifications.rs b/src/conf/notifications.rs index 70182f532..f600440fd 100644 --- a/src/conf/notifications.rs +++ b/src/conf/notifications.rs @@ -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, - /// 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, - #[serde(default = "internal_value_false", alias = "play-sound")] - play_sound: super::ToggleFlag, - #[serde(default = "none", alias = "sound-file")] - sound_file: Option, - } -); +/// 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, + /// 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, + #[serde(default = "internal_value_false", alias = "play-sound")] + pub play_sound: super::ToggleFlag, + #[serde(default = "none", alias = "sound-file")] + pub sound_file: Option, +} impl Default for NotificationsSettings { fn default() -> Self { diff --git a/src/conf/overrides.rs b/src/conf/overrides.rs new file mode 100644 index 000000000..733897ccf --- /dev/null +++ b/src/conf/overrides.rs @@ -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 . + */ + +//! 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, + #[doc = " Stop at the end instead of displaying next mail."] + #[doc = " Default: false"] + #[serde(alias = "pager-stop")] + #[serde(default)] + pub pager_stop: Option, + #[doc = " Always show headers when scrolling."] + #[doc = " Default: true"] + #[serde(alias = "headers-sticky")] + #[serde(default)] + pub headers_sticky: Option, + #[doc = " The height of the pager in mail view, in percent."] + #[doc = " Default: 80"] + #[serde(alias = "pager-ratio")] + #[serde(default)] + pub pager_ratio: Option, + #[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>, + #[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>, + #[doc = " Respect \"format=flowed\""] + #[doc = " Default: true"] + #[serde(alias = "format-flowed")] + #[serde(default)] + pub format_flowed: Option, + #[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, + #[doc = " Minimum text width in columns."] + #[doc = " Default: 80"] + #[serde(alias = "minimum-width")] + #[serde(default)] + pub minimum_width: Option, + #[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, +} +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, + #[doc = " Datetime formatting passed verbatim to strftime(3)."] + #[doc = " Default: %Y-%m-%d %T"] + #[serde(alias = "datetime-fmt")] + #[serde(default)] + pub datetime_fmt: Option>, + #[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, + #[doc = " Show only envelopes that match this query"] + #[doc = " Default: None"] + #[serde(default)] + pub filter: Option>, + #[serde(alias = "index-style")] + #[serde(default)] + pub index_style: Option, +} +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>, + #[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>, + #[serde(alias = "play-sound")] + #[serde(default)] + pub play_sound: Option, + #[serde(alias = "sound-file")] + #[serde(default)] + pub sound_file: Option>, +} +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, + #[serde(default)] + pub listing: Option, + #[serde(default)] + pub composing: Option, + #[serde(alias = "compact-listing")] + #[serde(default)] + pub compact_listing: Option, + #[serde(alias = "contact-list")] + #[serde(default)] + pub contact_list: Option, + #[serde(alias = "envelope-view")] + #[serde(default)] + pub envelope_view: Option, + #[serde(alias = "thread-view")] + #[serde(default)] + pub thread_view: Option, + #[serde(default)] + pub pager: Option, +} +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, + #[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>, + #[doc = " Embed editor (for terminal interfaces) instead of forking and waiting."] + #[serde(default)] + pub embed: Option, + #[doc = " Set \"format=flowed\" in plain text attachments."] + #[doc = " Default: true"] + #[serde(alias = "format-flowed")] + #[serde(default)] + pub format_flowed: Option, + #[doc = " Set default header values for new drafts"] + #[doc = " Default: empty"] + #[serde(alias = "default-header-values")] + #[serde(default)] + pub default_header_values: Option>, +} +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>, + #[serde(deserialize_with = "tag_set_de", alias = "ignore-tags")] + #[serde(default)] + pub ignore_tags: Option>, +} +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, + #[doc = " always sign sent messages"] + #[serde(alias = "auto-sign")] + #[serde(default)] + pub auto_sign: Option, + #[serde(default)] + pub key: Option>, + #[doc = " gpg binary name or file location to use"] + #[serde(alias = "gpg-binary")] + #[serde(default)] + pub gpg_binary: Option>, +} +impl Default for PGPSettingsOverride { + fn default() -> Self { + PGPSettingsOverride { + auto_verify_signatures: None, + auto_sign: None, + key: None, + gpg_binary: None, + } + } +} diff --git a/src/conf/pager.rs b/src/conf/pager.rs index 0f6587097..5365423a2 100644 --- a/src/conf/pager.rs +++ b/src/conf/pager.rs @@ -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, + /// A command to pipe mail output through for viewing in pager. + /// Default: None + #[serde(default = "none", deserialize_with = "non_empty_string")] + pub filter: Option, - /// 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, + /// 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, - /// 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 { diff --git a/src/conf/pgp.rs b/src/conf/pgp.rs index c6c00c783..3d0fd4297 100644 --- a/src/conf/pgp.rs +++ b/src/conf/pgp.rs @@ -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, + // https://tools.ietf.org/html/rfc4880#section-12.2 + #[serde(default = "none")] + pub key: Option, - /// gpg binary name or file location to use - #[serde(default, alias = "gpg-binary")] - gpg_binary: Option, - } -); + /// gpg binary name or file location to use + #[serde(default, alias = "gpg-binary")] + pub gpg_binary: Option, +} impl Default for PGPSettings { fn default() -> Self { diff --git a/src/conf/shortcuts.rs b/src/conf/shortcuts.rs index 320b30832..1ad69bac9 100644 --- a/src/conf/shortcuts.rs +++ b/src/conf/shortcuts.rs @@ -19,7 +19,6 @@ * along with meli. If not, see . */ -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 { diff --git a/src/conf/tags.rs b/src/conf/tags.rs index baa464f0e..a9d2bc6a1 100644 --- a/src/conf/tags.rs +++ b/src/conf/tags.rs @@ -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, - #[serde(default, deserialize_with = "tag_set_de", alias = "ignore-tags")] - ignore_tags: HashSet, - } -); +#[derive(Debug, Deserialize, Clone, Serialize)] +pub struct TagsSettings { + #[serde(default, deserialize_with = "tag_color_de")] + pub colors: HashMap, + #[serde(default, deserialize_with = "tag_set_de", alias = "ignore-tags")] + pub ignore_tags: HashSet, +} impl Default for TagsSettings { fn default() -> Self {