summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Dilly <dilly.stephan@gmail.com>2021-03-14 00:25:30 +0100
committerGitHub <noreply@github.com>2021-03-14 00:25:30 +0100
commit7d4b79606c5d71ef7f2f9fa4ccd96c5a8a05dcf8 (patch)
treefe2377dfefe5e86f043624ae5cd6d69d78039347
parent52bf018515c5d8c3e84514f81bae5979441151b2 (diff)
smarter config loading giving more diagnostics to the user about whats going wrong (#589)
-rw-r--r--src/app.rs9
-rw-r--r--src/keys.rs51
-rw-r--r--src/main.rs11
-rw-r--r--src/ui/style.rs36
4 files changed, 62 insertions, 45 deletions
diff --git a/src/app.rs b/src/app.rs
index 390f2f72..600f1a89 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -23,7 +23,7 @@ use crossbeam_channel::Sender;
use crossterm::event::{Event, KeyEvent};
use std::{
cell::{Cell, RefCell},
- path::{Path, PathBuf},
+ path::Path,
rc::Rc,
};
use tui::{
@@ -74,11 +74,12 @@ impl App {
pub fn new(
sender: &Sender<AsyncNotification>,
input: Input,
- theme_path: PathBuf,
+ theme: Theme,
+ key_config: KeyConfig,
) -> Self {
let queue = Queue::default();
- let theme = Rc::new(Theme::init(theme_path));
- let key_config = Rc::new(KeyConfig::init());
+ let theme = Rc::new(theme);
+ let key_config = Rc::new(key_config);
Self {
input,
diff --git a/src/keys.rs b/src/keys.rs
index 01ff9b50..18f8afea 100644
--- a/src/keys.rs
+++ b/src/keys.rs
@@ -5,12 +5,12 @@ use crate::get_app_config_path;
use anyhow::Result;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ron::{
- de::from_bytes,
+ self,
ser::{to_string_pretty, PrettyConfig},
};
use serde::{Deserialize, Serialize};
use std::{
- fs::File,
+ fs::{self, File},
io::{Read, Write},
path::PathBuf,
rc::Rc,
@@ -127,15 +127,14 @@ impl Default for KeyConfig {
}
impl KeyConfig {
- fn save(&self) -> Result<()> {
- let config_file = Self::get_config_file()?;
- let mut file = File::create(config_file)?;
+ fn save(&self, file: PathBuf) -> Result<()> {
+ let mut file = File::create(file)?;
let data = to_string_pretty(self, PrettyConfig::default())?;
file.write_all(data.as_bytes())?;
Ok(())
}
- fn get_config_file() -> Result<PathBuf> {
+ pub fn get_config_file() -> Result<PathBuf> {
let app_home = get_app_config_path()?;
Ok(app_home.join("key_config.ron"))
}
@@ -144,31 +143,31 @@ impl KeyConfig {
let mut f = File::open(config_file)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
- Ok(from_bytes(&buffer)?)
+ Ok(ron::de::from_bytes(&buffer)?)
}
- fn init_internal() -> Result<Self> {
- let file = Self::get_config_file()?;
+ pub fn init(file: PathBuf) -> Result<Self> {
if file.exists() {
- Ok(Self::read_file(file)?)
- } else {
- let def = Self::default();
- if def.save().is_err() {
- log::warn!(
- "failed to store default key config to disk."
- )
- }
- Ok(def)
- }
- }
+ match Self::read_file(file.clone()) {
+ Err(e) => {
+ let config_path = file.clone();
+ let config_path_old =
+ format!("{}.old", file.to_string_lossy());
+ fs::rename(
+ config_path.clone(),
+ config_path_old.clone(),
+ )?;
+
+ Self::default().save(file)?;
- pub fn init() -> Self {
- match Self::init_internal() {
- Ok(v) => v,
- Err(e) => {
- log::error!("failed loading key binding: {}", e);
- Self::default()
+ Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
+ e,config_path_old,config_path.to_string_lossy()))
+ }
+ Ok(res) => Ok(res),
}
+ } else {
+ Self::default().save(file)?;
+ Ok(Self::default())
}
}
diff --git a/src/main.rs b/src/main.rs
index deaa4704..cfae967f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -43,6 +43,7 @@ use crossterm::{
ExecutableCommand,
};
use input::{Input, InputEvent, InputState};
+use keys::KeyConfig;
use profiler::Profiler;
use scopeguard::defer;
use scopetime::scope_time;
@@ -61,6 +62,7 @@ use tui::{
backend::{Backend, CrosstermBackend},
Terminal,
};
+use ui::style::Theme;
static TICK_INTERVAL: Duration = Duration::from_secs(5);
static SPINNER_INTERVAL: Duration = Duration::from_millis(80);
@@ -88,6 +90,13 @@ fn main() -> Result<()> {
return Ok(());
}
+ let key_config = KeyConfig::init(KeyConfig::get_config_file()?)
+ .map_err(|e| eprintln!("KeyConfig loading error: {}", e))
+ .unwrap_or_default();
+ let theme = Theme::init(cliargs.theme)
+ .map_err(|e| eprintln!("Theme loading error: {}", e))
+ .unwrap_or_default();
+
setup_terminal()?;
defer! {
shutdown_terminal().expect("shutdown failed");
@@ -105,7 +114,7 @@ fn main() -> Result<()> {
let ticker = tick(TICK_INTERVAL);
let spinner_ticker = tick(SPINNER_INTERVAL);
- let mut app = App::new(&tx_git, input, cliargs.theme);
+ let mut app = App::new(&tx_git, input, theme, key_config);
let mut spinner = Spinner::default();
let mut first_update = true;
diff --git a/src/ui/style.rs b/src/ui/style.rs
index 2a2aa345..b06d2750 100644
--- a/src/ui/style.rs
+++ b/src/ui/style.rs
@@ -9,7 +9,7 @@ use ron::{
};
use serde::{Deserialize, Serialize};
use std::{
- fs::File,
+ fs::{self, File},
io::{Read, Write},
path::PathBuf,
rc::Rc,
@@ -250,22 +250,30 @@ impl Theme {
Ok(from_bytes(&buffer)?)
}
- fn init_internal(theme: PathBuf) -> Result<Self> {
- if theme.exists() {
- Ok(Self::read_file(theme)?)
- } else {
- // This will only be called when theme.ron doesn't already exists
- let def = Self::default();
- if def.save(theme).is_err() {
- log::warn!("failed to store default theme to disk.")
+ pub fn init(file: PathBuf) -> Result<Self> {
+ if file.exists() {
+ match Self::read_file(file.clone()) {
+ Err(e) => {
+ let config_path = file.clone();
+ let config_path_old =
+ format!("{}.old", file.to_string_lossy());
+ fs::rename(
+ config_path.clone(),
+ config_path_old.clone(),
+ )?;
+
+ Self::default().save(file)?;
+
+ Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
+ e,config_path_old,config_path.to_string_lossy()))
+ }
+ Ok(res) => Ok(res),
}
- Ok(def)
+ } else {
+ Self::default().save(file)?;
+ Ok(Self::default())
}
}
-
- pub fn init(theme_path: PathBuf) -> Self {
- Self::init_internal(theme_path).unwrap_or_default()
- }
}
impl Default for Theme {