ui: add shortcut! macro to compare shortcuts values

This is used in process_event() functions of UI Components. When a key
has been input we have to compare it with the configured shortcuts from
a hashmap.

Add shortcut! macro that checks shortcut hashmaps for the given name and
doesn't panic if it's missing.
jmap
Manos Pitsidianakis 2019-11-28 22:16:56 +02:00
parent bb486ca9d8
commit c04513ac94
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
12 changed files with 177 additions and 62 deletions

View File

@ -583,10 +583,12 @@ impl Component for ContactList {
return true;
}
}
let shortcuts = &self.get_shortcuts(context)[Self::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
if self.view.is_none() {
match *event {
UIEvent::Input(ref key) if key == shortcuts["create_contact"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["create_contact"]) =>
{
let mut manager = ContactManager::default();
manager.set_parent_id(self.id);
manager.account_pos = self.account_pos;
@ -597,7 +599,10 @@ impl Component for ContactList {
return true;
}
UIEvent::Input(ref key) if key == shortcuts["edit_contact"] && self.length > 0 => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["edit_contact"])
&& self.length > 0 =>
{
let account = &mut context.accounts[self.account_pos];
let book = &mut account.address_book;
let card = book[&self.id_positions[self.cursor_pos]].clone();
@ -611,7 +616,10 @@ impl Component for ContactList {
return true;
}
UIEvent::Input(ref key) if key == shortcuts["mail_contact"] && self.length > 0 => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["mail_contact"])
&& self.length > 0 =>
{
let account = &context.accounts[self.account_pos];
let book = &account.address_book;
let card = &book[&self.id_positions[self.cursor_pos]];
@ -625,7 +633,9 @@ impl Component for ContactList {
return true;
}
UIEvent::Input(ref key) if key == shortcuts["next_account"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["next_account"]) =>
{
let amount = if self.cmd_buf.is_empty() {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
@ -660,7 +670,9 @@ impl Component for ContactList {
return true;
}
UIEvent::Input(ref key) if key == shortcuts["prev_account"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["prev_account"]) =>
{
let amount = if self.cmd_buf.is_empty() {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
@ -694,7 +706,9 @@ impl Component for ContactList {
}
return true;
}
UIEvent::Input(ref k) if k == shortcuts["toggle_menu_visibility"] => {
UIEvent::Input(ref k)
if shortcut!(k == shortcuts[Self::DESCRIPTION]["toggle_menu_visibility"]) =>
{
self.menu_visibility = !self.menu_visibility;
self.set_dirty();
}

View File

@ -283,10 +283,11 @@ impl Component for Listing {
return true;
}
let shortcuts = &self.get_shortcuts(context)[Listing::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
match *event {
UIEvent::Input(ref k)
if k == shortcuts["next_folder"] || k == shortcuts["prev_folder"] =>
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["next_folder"])
|| shortcut!(k == shortcuts[Listing::DESCRIPTION]["prev_folder"]) =>
{
let amount = if self.cmd_buf.is_empty() {
1
@ -305,7 +306,9 @@ impl Component for Listing {
};
let folder_length = context.accounts[self.cursor_pos.0].len();
match k {
k if k == shortcuts["next_folder"] && folder_length > 0 => {
k if shortcut!(k == shortcuts[Listing::DESCRIPTION]["next_folder"])
&& folder_length > 0 =>
{
if self.cursor_pos.1 + amount < folder_length {
self.cursor_pos.1 += amount;
self.component.set_coordinates((
@ -318,7 +321,7 @@ impl Component for Listing {
return true;
}
}
k if k == shortcuts["prev_folder"] => {
k if shortcut!(k == shortcuts[Listing::DESCRIPTION]["prev_folder"]) => {
if self.cursor_pos.1 >= amount {
self.cursor_pos.1 -= amount;
self.component.set_coordinates((
@ -357,7 +360,8 @@ impl Component for Listing {
return true;
}
UIEvent::Input(ref k)
if k == shortcuts["next_account"] || k == shortcuts["prev_account"] =>
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["next_account"])
|| shortcut!(k == shortcuts[Listing::DESCRIPTION]["prev_account"]) =>
{
let amount = if self.cmd_buf.is_empty() {
1
@ -375,7 +379,7 @@ impl Component for Listing {
return true;
};
match k {
k if k == shortcuts["next_account"] => {
k if shortcut!(k == shortcuts[Listing::DESCRIPTION]["next_account"]) => {
if self.cursor_pos.0 + amount < self.accounts.len() {
self.cursor_pos = (self.cursor_pos.0 + amount, 0);
self.component.set_coordinates((self.cursor_pos.0, 0, None));
@ -384,7 +388,7 @@ impl Component for Listing {
return true;
}
}
k if k == shortcuts["prev_account"] => {
k if shortcut!(k == shortcuts[Listing::DESCRIPTION]["prev_account"]) => {
if self.cursor_pos.0 >= amount {
self.cursor_pos = (self.cursor_pos.0 - amount, 0);
self.component.set_coordinates((self.cursor_pos.0, 0, None));
@ -502,7 +506,9 @@ impl Component for Listing {
self.component.set_movement(PageMovement::Down(amount));
return true;
}
UIEvent::Input(ref key) if key == shortcuts["prev_page"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Listing::DESCRIPTION]["prev_page"]) =>
{
let mult = if self.cmd_buf.is_empty() {
1
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
@ -521,7 +527,9 @@ impl Component for Listing {
self.component.set_movement(PageMovement::PageUp(mult));
return true;
}
UIEvent::Input(ref key) if key == shortcuts["next_page"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Listing::DESCRIPTION]["next_page"]) =>
{
let mult = if self.cmd_buf.is_empty() {
1
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
@ -548,17 +556,23 @@ impl Component for Listing {
self.component.set_movement(PageMovement::End);
return true;
}
UIEvent::Input(ref k) if k == shortcuts["toggle_menu_visibility"] => {
UIEvent::Input(ref k)
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["toggle_menu_visibility"]) =>
{
self.menu_visibility = !self.menu_visibility;
self.set_dirty();
}
UIEvent::Input(ref k) if k == shortcuts["new_mail"] => {
UIEvent::Input(ref k)
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["new_mail"]) =>
{
context
.replies
.push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0, None))));
return true;
}
UIEvent::Input(ref key) if key == shortcuts["search"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Listing::DESCRIPTION]["search"]) =>
{
context
.replies
.push_back(UIEvent::ExInput(Key::Paste("filter ".to_string())));
@ -567,7 +581,9 @@ impl Component for Listing {
.push_back(UIEvent::ChangeMode(UIMode::Execute));
return true;
}
UIEvent::Input(ref key) if key == shortcuts["set_seen"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Listing::DESCRIPTION]["set_seen"]) =>
{
let mut event = UIEvent::Action(Action::Listing(ListingAction::SetSeen));
if match self.component {
Plain(ref mut l) => l.process_event(&mut event, context),

View File

@ -1063,10 +1063,15 @@ impl Component for CompactListing {
return true;
}
let shortcuts = &self.get_shortcuts(context)[CompactListing::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
if self.length > 0 {
match *event {
UIEvent::Input(ref k) if !self.unfocused && k == shortcuts["open_thread"] => {
UIEvent::Input(ref k)
if !self.unfocused
&& shortcut!(
k == shortcuts[CompactListing::DESCRIPTION]["open_thread"]
) =>
{
if self.filtered_selection.is_empty() {
self.view = ThreadView::new(self.cursor_pos, None, context);
} else {
@ -1087,7 +1092,12 @@ impl Component for CompactListing {
self.dirty = true;
return true;
}
UIEvent::Input(ref k) if self.unfocused && k == shortcuts["exit_thread"] => {
UIEvent::Input(ref k)
if self.unfocused
&& shortcut!(
k == shortcuts[CompactListing::DESCRIPTION]["exit_thread"]
) =>
{
self.unfocused = false;
self.dirty = true;
/* If self.row_updates is not empty and we exit a thread, the row_update events
@ -1096,7 +1106,12 @@ impl Component for CompactListing {
self.force_draw = true;
return true;
}
UIEvent::Input(ref key) if !self.unfocused && key == shortcuts["select_entry"] => {
UIEvent::Input(ref key)
if !self.unfocused
&& shortcut!(
key == shortcuts[CompactListing::DESCRIPTION]["select_entry"]
) =>
{
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2, context);
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
}

View File

@ -1010,10 +1010,15 @@ impl Component for ConversationsListing {
return true;
}
let shortcuts = &self.get_shortcuts(context)[ConversationsListing::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
if self.length > 0 {
match *event {
UIEvent::Input(ref k) if !self.unfocused && k == shortcuts["open_thread"] => {
UIEvent::Input(ref k)
if !self.unfocused
&& shortcut!(
k == shortcuts[ConversationsListing::DESCRIPTION]["open_thread"]
) =>
{
if self.length == 0 {
return true;
}
@ -1039,7 +1044,12 @@ impl Component for ConversationsListing {
self.dirty = true;
return true;
}
UIEvent::Input(ref k) if self.unfocused && k == shortcuts["exit_thread"] => {
UIEvent::Input(ref k)
if self.unfocused
&& shortcut!(
k == shortcuts[ConversationsListing::DESCRIPTION]["exit_thread"]
) =>
{
self.unfocused = false;
self.dirty = true;
/* If self.row_updates is not empty and we exit a thread, the row_update events
@ -1048,7 +1058,12 @@ impl Component for ConversationsListing {
self.force_draw = true;
return true;
}
UIEvent::Input(ref key) if !self.unfocused && key == shortcuts["select_entry"] => {
UIEvent::Input(ref key)
if !self.unfocused
&& shortcut!(
key == shortcuts[ConversationsListing::DESCRIPTION]["select_entry"]
) =>
{
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2, context);
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
return true;

View File

@ -891,10 +891,13 @@ impl Component for PlainListing {
return true;
}
let shortcuts = &self.get_shortcuts(context)[PlainListing::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
if self.length > 0 {
match *event {
UIEvent::Input(ref k) if !self.unfocused && k == shortcuts["open_thread"] => {
UIEvent::Input(ref k)
if !self.unfocused
&& shortcut!(k == shortcuts[PlainListing::DESCRIPTION]["open_thread"]) =>
{
let env_hash = self.get_env_under_cursor(self.cursor_pos.2, context);
let temp = (self.cursor_pos.0, self.cursor_pos.1, env_hash);
self.view = MailView::new(temp, None, None);
@ -902,7 +905,10 @@ impl Component for PlainListing {
self.dirty = true;
return true;
}
UIEvent::Input(ref k) if self.unfocused && k == shortcuts["exit_thread"] => {
UIEvent::Input(ref k)
if self.unfocused
&& shortcut!(k == shortcuts[PlainListing::DESCRIPTION]["exit_thread"]) =>
{
self.unfocused = false;
self.dirty = true;
/* If self.row_updates is not empty and we exit a thread, the row_update events
@ -911,7 +917,12 @@ impl Component for PlainListing {
self.force_draw = true;
return true;
}
UIEvent::Input(ref key) if !self.unfocused && key == shortcuts["select_entry"] => {
UIEvent::Input(ref key)
if !self.unfocused
&& shortcut!(
key == shortcuts[PlainListing::DESCRIPTION]["select_entry"]
) =>
{
let env_hash = self.get_env_under_cursor(self.cursor_pos.2, context);
self.selection.entry(env_hash).and_modify(|e| *e = !*e);
}

View File

@ -654,8 +654,8 @@ impl Component for MailView {
}
}
_ => match event {
UIEvent::Input(ref k)
if k == shortcuts[Pager::DESCRIPTION]["scroll_up"]
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Pager::DESCRIPTION]["scroll_up"])
&& !context.settings.pager.headers_sticky
&& self.headers_cursor <= self.headers_no =>
{
@ -670,8 +670,8 @@ impl Component for MailView {
self.pager.set_dirty();
return true;
}
UIEvent::Input(ref k)
if k == shortcuts[Pager::DESCRIPTION]["scroll_down"]
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Pager::DESCRIPTION]["scroll_down"])
&& !context.settings.pager.headers_sticky
&& self.headers_cursor < self.headers_no =>
{
@ -688,9 +688,11 @@ impl Component for MailView {
},
}
let shortcuts = &self.get_shortcuts(context)[MailView::DESCRIPTION];
let shortcuts = &self.get_shortcuts(context);
match *event {
UIEvent::Input(ref k) if k == shortcuts["reply"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["reply"]) =>
{
let account = &context.accounts[self.coordinates.0];
let folder_hash = account[self.coordinates.1].unwrap().folder.hash();
let envelope: EnvelopeRef = account.collection.get_env(self.coordinates.2);
@ -707,7 +709,9 @@ impl Component for MailView {
))));
return true;
}
UIEvent::Input(ref k) if k == shortcuts["edit"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["edit"]) =>
{
context.replies.push_back(UIEvent::Action(Tab(Edit(
self.coordinates.0,
self.coordinates.2,
@ -716,7 +720,9 @@ impl Component for MailView {
}
UIEvent::Input(ref key)
if !self.mode.is_contact_selector()
&& key == shortcuts["add_addresses_to_contacts"] =>
&& shortcut!(
key == shortcuts[MailView::DESCRIPTION]["add_addresses_to_contacts"]
) =>
{
let account = &context.accounts[self.coordinates.0];
let envelope: EnvelopeRef = account.collection.get_env(self.coordinates.2);
@ -763,7 +769,7 @@ impl Component for MailView {
}
UIEvent::Input(ref key)
if (self.mode == ViewMode::Normal || self.mode == ViewMode::Subview)
&& key == shortcuts["view_raw_source"] =>
&& shortcut!(key == shortcuts[MailView::DESCRIPTION]["view_raw_source"]) =>
{
self.mode = ViewMode::Raw;
self.set_dirty();
@ -774,7 +780,9 @@ impl Component for MailView {
|| self.mode == ViewMode::Subview
|| self.mode == ViewMode::Url
|| self.mode == ViewMode::Raw)
&& key == shortcuts["return_to_normal_view"] =>
&& shortcut!(
key == shortcuts[MailView::DESCRIPTION]["return_to_normal_view"]
) =>
{
self.mode = ViewMode::Normal;
self.set_dirty();
@ -783,7 +791,7 @@ impl Component for MailView {
UIEvent::Input(ref key)
if (self.mode == ViewMode::Normal || self.mode == ViewMode::Subview)
&& !self.cmd_buf.is_empty()
&& key == shortcuts["open_mailcap"] =>
&& shortcut!(key == shortcuts[MailView::DESCRIPTION]["open_mailcap"]) =>
{
let lidx = self.cmd_buf.parse::<usize>().unwrap();
self.cmd_buf.clear();
@ -840,7 +848,7 @@ impl Component for MailView {
}
}
UIEvent::Input(ref key)
if key == shortcuts["open_attachment"]
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["open_attachment"])
&& !self.cmd_buf.is_empty()
&& (self.mode == ViewMode::Normal || self.mode == ViewMode::Subview) =>
{
@ -972,7 +980,9 @@ impl Component for MailView {
}
};
}
UIEvent::Input(ref key) if key == shortcuts["toggle_expand_headers"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["toggle_expand_headers"]) =>
{
self.expand_headers = !self.expand_headers;
self.dirty = true;
return true;
@ -980,7 +990,7 @@ impl Component for MailView {
UIEvent::Input(ref key)
if !self.cmd_buf.is_empty()
&& self.mode == ViewMode::Url
&& key == shortcuts["go_to_url"] =>
&& shortcut!(key == shortcuts[MailView::DESCRIPTION]["go_to_url"]) =>
{
let lidx = self.cmd_buf.parse::<usize>().unwrap();
self.cmd_buf.clear();
@ -1038,7 +1048,7 @@ impl Component for MailView {
}
UIEvent::Input(ref key)
if (self.mode == ViewMode::Normal || self.mode == ViewMode::Url)
&& key == shortcuts["toggle_url_mode"] =>
&& shortcut!(key == shortcuts[MailView::DESCRIPTION]["toggle_url_mode"]) =>
{
match self.mode {
ViewMode::Normal => self.mode = ViewMode::Url,

View File

@ -154,6 +154,9 @@ impl Component for HtmlView {
}
false
}
fn get_shortcuts(&self, context: &Context) -> ShortcutMaps {
self.pager.get_shortcuts(context)
}
fn is_dirty(&self) -> bool {
self.pager.is_dirty()
}

View File

@ -966,7 +966,7 @@ impl Component for ThreadView {
return true;
}
let shortcuts = &self.get_shortcuts(context)[ThreadView::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
match *event {
UIEvent::Input(Key::Up) => {
if self.cursor_pos > 0 {
@ -983,11 +983,15 @@ impl Component for ThreadView {
}
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["prev_page"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[ThreadView::DESCRIPTION]["prev_page"]) =>
{
self.movement = Some(PageMovement::PageUp(1));
self.dirty = true;
}
UIEvent::Input(ref key) if *key == shortcuts["next_page"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[ThreadView::DESCRIPTION]["next_page"]) =>
{
self.movement = Some(PageMovement::PageDown(1));
self.dirty = true;
}
@ -1009,19 +1013,25 @@ impl Component for ThreadView {
self.set_dirty();
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["toggle_mailview"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[ThreadView::DESCRIPTION]["toggle_mailview"]) =>
{
self.show_mailview = !self.show_mailview;
self.initiated = false;
self.set_dirty();
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["toggle_threadview"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[ThreadView::DESCRIPTION]["toggle_threadview"]) =>
{
self.show_thread = !self.show_thread;
self.initiated = false;
self.set_dirty();
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["reverse_thread_order"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[ThreadView::DESCRIPTION]["reverse_thread_order"]) =>
{
self.reversed = !self.reversed;
let expanded_hash = self.entries[self.expanded_pos].index.1;
self.initiate(Some(expanded_hash), context);
@ -1029,7 +1039,9 @@ impl Component for ThreadView {
self.dirty = true;
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["collapse_subtree"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[ThreadView::DESCRIPTION]["collapse_subtree"]) =>
{
let current_pos = self.current_pos();
self.entries[current_pos].hidden = !self.entries[current_pos].hidden;
self.entries[current_pos].dirty = true;

View File

@ -577,14 +577,18 @@ impl Component for Pager {
context.dirty_areas.push_back(area);
}
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
let shortcuts = &self.get_shortcuts(context)[Self::DESCRIPTION];
let shortcuts = self.get_shortcuts(context);
match event {
UIEvent::Input(ref key) if *key == shortcuts["scroll_up"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["scroll_up"]) =>
{
self.cursor.1 = self.cursor.1.saturating_sub(1);
self.dirty = true;
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["scroll_down"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["scroll_down"]) =>
{
self.cursor.1 = self.cursor.1 + 1;
self.dirty = true;
return true;
@ -609,12 +613,16 @@ impl Component for Pager {
self.dirty = true;
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["page_up"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["page_up"]) =>
{
self.movement = Some(PageMovement::PageUp(1));
self.dirty = true;
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["page_down"] => {
UIEvent::Input(ref key)
if shortcut!(key == shortcuts[Self::DESCRIPTION]["page_down"]) =>
{
self.movement = Some(PageMovement::PageDown(1));
self.dirty = true;
return true;
@ -1564,8 +1572,7 @@ impl Component for Tabbed {
self.dirty = false;
}
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
let our_shortcuts = self.get_shortcuts(context);
let shortcuts: &ShortcutMap = &our_shortcuts["general"];
let shortcuts = self.get_shortcuts(context);
match *event {
UIEvent::Input(Key::Alt(no)) if no >= '1' && no <= '9' => {
let no = no as usize - '1' as usize;
@ -1582,7 +1589,7 @@ impl Component for Tabbed {
}
return true;
}
UIEvent::Input(ref key) if *key == shortcuts["next_tab"] => {
UIEvent::Input(ref key) if shortcut!(key == shortcuts["general"]["next_tab"]) => {
self.cursor_pos = (self.cursor_pos + 1) % self.children.len();
context
.replies

View File

@ -28,6 +28,7 @@ pub mod composing;
pub mod notifications;
pub mod pager;
pub mod pgp;
#[macro_use]
pub mod shortcuts;
pub mod terminal;

View File

@ -2,6 +2,16 @@ use crate::terminal::Key;
//use std::any::TypeId;
use fnv::FnvHashMap;
#[macro_export]
macro_rules! shortcut {
($key:ident == $shortcuts:ident[$section:expr][$val:literal]) => {
$shortcuts[$section]
.get($val)
.map(|v| v == $key)
.unwrap_or(false)
};
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Shortcuts {
#[serde(default)]

View File

@ -63,6 +63,7 @@ pub use crate::state::*;
pub mod components;
pub use crate::components::*;
#[macro_use]
pub mod conf;
pub use crate::conf::*;