#![windows_subsystem = "windows"]
#![allow(clippy::vec_init_then_push)]
#[cfg(feature = "message-box")]
mod alert_service;
mod config;
mod content;
mod context;
mod error;
mod file_editor;
mod filename;
mod filter;
mod logger;
mod note;
mod process_ext;
mod settings;
#[cfg(feature = "viewer")]
mod viewer;
mod workflow;
#[cfg(feature = "message-box")]
use crate::alert_service::AlertService;
use crate::config::backup_config_file;
use crate::config::CFG;
use crate::config::CFG_FILE_LOADING;
use crate::config::CONFIG_PATH;
#[cfg(feature = "read-clipboard")]
use crate::error::NoteError;
#[cfg(feature = "read-clipboard")]
use crate::error::WorkflowError;
use crate::logger::AppLogger;
use crate::settings::ARGS;
#[cfg(feature = "read-clipboard")]
use crate::settings::LAUNCH_EDITOR;
#[cfg(feature = "message-box")]
use crate::settings::RUNS_ON_CONSOLE;
use crate::workflow::run;
#[cfg(feature = "read-clipboard")]
use copypasta::ClipboardContext;
#[cfg(feature = "read-clipboard")]
use copypasta::ClipboardProvider;
use error::FileError;
use semver::Version;
use serde::Serialize;
use std::path::PathBuf;
use std::process;
use time;
const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
const MIN_CONFIG_FILE_VERSION: Option<&'static str> = Some("1.17.1");
const AUTHOR: Option<&str> = option_env!("CARGO_PKG_AUTHORS");
const COPYRIGHT_FROM: &str = "2020";
#[derive(Debug, PartialEq, Serialize)]
struct About {
version: String,
features: Vec<String>,
config_file_path: String,
copyright: String,
}
fn main() {
AppLogger::init();
lazy_static::initialize(&CFG);
let level = ARGS.debug.unwrap_or(CFG.arg_default.debug);
AppLogger::set_max_level(level);
AppLogger::set_popup_always_enabled(ARGS.popup || CFG.arg_default.popup);
let cfg_file_loading = &*CFG_FILE_LOADING.read().unwrap();
let cfg_file_loading_err = cfg_file_loading.as_ref().err().map(|e| e.to_string());
let cfg_file_version = Version::parse(&*CFG.version);
let cfg_file_version_err = cfg_file_version.as_ref().err().map(|e| e.to_string());
let cfg_err = cfg_file_loading_err.or(cfg_file_version_err);
let config_file_version = match cfg_err {
None => cfg_file_version.ok(),
Some(e) => {
log::error!("{}", FileError::ConfigFileLoadParseWrite { error: e });
if let Err(e) = backup_config_file() {
log::error!(
"{}",
FileError::ConfigFileBackup {
error: e.to_string()
}
.to_string()
);
AppLogger::flush();
process::exit(5);
};
None
}
};
if let Some(config_file_version) = config_file_version {
if config_file_version < Version::parse(MIN_CONFIG_FILE_VERSION.unwrap_or("0.0.0")).unwrap()
{
log::error!(
"{}",
FileError::ConfigFileVersionMismatch {
config_file_version: config_file_version.to_string(),
min_version: MIN_CONFIG_FILE_VERSION.unwrap_or("0.0.0").to_string(),
}
.to_string()
);
if let Err(e) = backup_config_file() {
log::error!(
"{}",
FileError::ConfigFileBackup {
error: e.to_string()
}
.to_string()
);
AppLogger::flush();
process::exit(5);
};
};
};
if ARGS.version {
#[allow(unused_mut)]
let mut features = Vec::new();
#[cfg(feature = "message-box")]
features.push("message-box".to_string());
#[cfg(feature = "viewer")]
features.push("viewer".to_string());
#[cfg(feature = "renderer")]
features.push("renderer".to_string());
#[cfg(feature = "clipboard")]
features.push("clipboard".to_string());
let about = About {
version: VERSION.unwrap_or("unknown").to_string(),
features,
config_file_path: CONFIG_PATH
.as_ref()
.unwrap_or(&PathBuf::new())
.to_str()
.unwrap_or("")
.to_string(),
copyright: format!(
"© {}-{} {}",
COPYRIGHT_FROM,
time::OffsetDateTime::now_utc().year(),
AUTHOR.unwrap()
),
};
let mut msg = serde_yaml::to_string(&about).unwrap_or_else(|_| "unknown".to_string());
msg.push_str("---");
println!("{}", msg);
#[cfg(feature = "message-box")]
if !*RUNS_ON_CONSOLE && !ARGS.batch {
let _ = AlertService::push_str(msg);
};
AppLogger::flush();
process::exit(0);
};
let res = run();
match res {
Err(ref e) => {
log::error!("{}", e);
}
Ok(ref path) => {
if let Some(p) = &ARGS.export {
if p.as_os_str().to_str().unwrap_or_default() != "-" {
println!("{}", path.to_str().unwrap_or_default());
}
} else {
println!("{}", path.to_str().unwrap_or_default());
}
}
};
AppLogger::flush();
#[cfg(feature = "read-clipboard")]
if (*LAUNCH_EDITOR && !ARGS.batch && CFG.clipboard.read_enabled && CFG.clipboard.empty_enabled)
|| matches!(
&res,
Err(WorkflowError::Note {
source: NoteError::InvalidClipboardYaml { .. },
})
)
{
if let Ok(mut ctx) = ClipboardContext::new() {
let _ = ctx.set_contents("".to_string());
};
}
if res.is_err() {
process::exit(1);
}
}