refactor: adjust all path methods and reduce unwrap

This commit is contained in:
GyDi
2022-11-18 09:35:05 +08:00
parent be81cd72af
commit 34daffbc96
11 changed files with 204 additions and 181 deletions

View File

@@ -1,47 +1,36 @@
use anyhow::{Context, Result};
use anyhow::{anyhow, bail, Context, Result};
use serde::{de::DeserializeOwned, Serialize};
use serde_yaml::{Mapping, Value};
use std::{fs, path::PathBuf};
/// read data from yaml as struct T
pub fn read_yaml<T: DeserializeOwned + Default>(path: PathBuf) -> T {
pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
if !path.exists() {
log::error!(target: "app", "file not found \"{}\"", path.display());
return T::default();
bail!("file not found \"{}\"", path.display());
}
let yaml_str = fs::read_to_string(&path).unwrap_or("".into());
let yaml_str = fs::read_to_string(&path)
.context(format!("failed to read the file \"{}\"", path.display()))?;
match serde_yaml::from_str::<T>(&yaml_str) {
Ok(val) => val,
Err(_) => {
log::error!(target: "app", "failed to read yaml file \"{}\"", path.display());
T::default()
}
}
serde_yaml::from_str::<T>(&yaml_str).context(format!(
"failed to read the file with yaml format \"{}\"",
path.display()
))
}
/// read mapping from yaml fix #165
pub fn read_merge_mapping(path: PathBuf) -> Mapping {
let map = Mapping::new();
pub fn read_merge_mapping(path: &PathBuf) -> Result<Mapping> {
let mut val: Value = read_yaml(path)?;
val.apply_merge()
.context(format!("failed to apply merge \"{}\"", path.display()))?;
if !path.exists() {
log::error!(target: "app", "file not found \"{}\"", path.display());
return map;
}
let yaml_str = fs::read_to_string(&path).unwrap_or("".into());
match serde_yaml::from_str::<Value>(&yaml_str) {
Ok(mut val) => {
crate::log_err!(val.apply_merge());
val.as_mapping().unwrap_or(&map).to_owned()
}
Err(_) => {
log::error!(target: "app", "failed to read yaml file \"{}\"", path.display());
map
}
}
Ok(val
.as_mapping()
.ok_or(anyhow!(
"failed to transform to yaml mapping \"{}\"",
path.display()
))?
.to_owned())
}
/// save the data to the file

View File

@@ -1,5 +1,5 @@
use anyhow::Result;
use std::path::PathBuf;
use std::{env::temp_dir, path::PathBuf};
use tauri::{
api::path::{home_dir, resource_dir},
Env, PackageInfo,
@@ -13,7 +13,6 @@ static APP_DIR: &str = "clash-verge-dev";
static CLASH_CONFIG: &str = "config.yaml";
static VERGE_CONFIG: &str = "verge.yaml";
static PROFILE_YAML: &str = "profiles.yaml";
static CLASH_RUNTIME_YAML: &str = "clash-verge-runtime.yaml";
static mut RESOURCE_DIR: Option<PathBuf> = None;
@@ -21,7 +20,7 @@ static mut RESOURCE_DIR: Option<PathBuf> = None;
#[allow(unused)]
static mut PORTABLE_FLAG: bool = false;
pub static mut APP_VERSION: &str = "v1.1.1";
pub static mut APP_VERSION: &str = "v1.1.2";
/// initialize portable flag
#[cfg(target_os = "windows")]
@@ -42,29 +41,37 @@ pub unsafe fn init_portable_flag() -> Result<()> {
}
/// get the verge app home dir
pub fn app_home_dir() -> PathBuf {
pub fn app_home_dir() -> Result<PathBuf> {
#[cfg(target_os = "windows")]
unsafe {
use tauri::utils::platform::current_exe;
if !PORTABLE_FLAG {
home_dir().unwrap().join(".config").join(APP_DIR)
Ok(home_dir()
.ok_or(anyhow::anyhow!("failed to get app home dir"))?
.join(".config")
.join(APP_DIR))
} else {
let app_exe = current_exe().unwrap();
let app_exe = dunce::canonicalize(app_exe).unwrap();
let app_dir = app_exe.parent().unwrap();
PathBuf::from(app_dir).join(".config").join(APP_DIR)
let app_exe = current_exe()?;
let app_exe = dunce::canonicalize(app_exe)?;
let app_dir = app_exe
.parent()
.ok_or(anyhow::anyhow!("failed to get the portable app dir"))?;
Ok(PathBuf::from(app_dir).join(".config").join(APP_DIR))
}
}
#[cfg(not(target_os = "windows"))]
home_dir().unwrap().join(".config").join(APP_DIR)
Ok(home_dir()
.ok_or(anyhow::anyhow!("failed to get the app home dir"))?
.join(".config")
.join(APP_DIR))
}
/// get the resources dir
pub fn app_resources_dir(package_info: &PackageInfo) -> PathBuf {
pub fn app_resources_dir(package_info: &PackageInfo) -> Result<PathBuf> {
let res_dir = resource_dir(package_info, &Env::default())
.unwrap()
.ok_or(anyhow::anyhow!("failed to get the resource dir"))?
.join("resources");
unsafe {
@@ -75,37 +82,49 @@ pub fn app_resources_dir(package_info: &PackageInfo) -> PathBuf {
APP_VERSION = Box::leak(Box::new(ver_str));
}
res_dir
Ok(res_dir)
}
/// profiles dir
pub fn app_profiles_dir() -> PathBuf {
app_home_dir().join("profiles")
pub fn app_profiles_dir() -> Result<PathBuf> {
Ok(app_home_dir()?.join("profiles"))
}
/// logs dir
pub fn app_logs_dir() -> PathBuf {
app_home_dir().join("logs")
pub fn app_logs_dir() -> Result<PathBuf> {
Ok(app_home_dir()?.join("logs"))
}
pub fn clash_path() -> PathBuf {
app_home_dir().join(CLASH_CONFIG)
pub fn clash_path() -> Result<PathBuf> {
Ok(app_home_dir()?.join(CLASH_CONFIG))
}
pub fn verge_path() -> PathBuf {
app_home_dir().join(VERGE_CONFIG)
pub fn verge_path() -> Result<PathBuf> {
Ok(app_home_dir()?.join(VERGE_CONFIG))
}
pub fn profiles_path() -> PathBuf {
app_home_dir().join(PROFILE_YAML)
pub fn profiles_path() -> Result<PathBuf> {
Ok(app_home_dir()?.join(PROFILE_YAML))
}
pub fn clash_runtime_yaml() -> PathBuf {
app_home_dir().join(CLASH_RUNTIME_YAML)
pub fn clash_runtime_yaml() -> Result<PathBuf> {
Ok(app_home_dir()?.join("clash-verge-runtime.yaml"))
}
pub fn clash_pid_path() -> PathBuf {
unsafe { RESOURCE_DIR.clone().unwrap().join("clash.pid") }
pub fn clash_check_yaml() -> Result<PathBuf> {
Ok(temp_dir().join("clash-verge-check.yaml"))
}
pub fn app_res_dir() -> Result<PathBuf> {
unsafe {
Ok(RESOURCE_DIR
.clone()
.ok_or(anyhow::anyhow!("failed to get the resource dir"))?)
}
}
pub fn clash_pid_path() -> Result<PathBuf> {
unsafe { Ok(RESOURCE_DIR.clone().unwrap().join("clash.pid")) }
}
#[cfg(windows)]

View File

@@ -12,7 +12,7 @@ use tauri::PackageInfo;
/// initialize this instance's log file
fn init_log() -> Result<()> {
let log_dir = dirs::app_logs_dir();
let log_dir = dirs::app_logs_dir()?;
if !log_dir.exists() {
let _ = fs::create_dir_all(&log_dir);
}
@@ -54,42 +54,40 @@ pub fn init_config() -> Result<()> {
let _ = init_log();
let app_dir = dirs::app_home_dir();
let profiles_dir = dirs::app_profiles_dir();
let _ = dirs::app_home_dir().map(|app_dir| {
if !app_dir.exists() {
let _ = fs::create_dir_all(&app_dir);
}
if !app_dir.exists() {
let _ = fs::create_dir_all(&app_dir);
}
if !profiles_dir.exists() {
let _ = fs::create_dir_all(&profiles_dir);
}
// // target path
// let clash_path = app_dir.join("config.yaml");
// let verge_path = app_dir.join("verge.yaml");
// let profile_path = app_dir.join("profiles.yaml");
// target path
let clash_path = app_dir.join("config.yaml");
let verge_path = app_dir.join("verge.yaml");
let profile_path = app_dir.join("profiles.yaml");
// if !clash_path.exists() {
// fs::File::create(clash_path)?.write(tmpl::CLASH_CONFIG)?;
// }
// if !verge_path.exists() {
// fs::File::create(verge_path)?.write(tmpl::VERGE_CONFIG)?;
// }
// if !profile_path.exists() {
// fs::File::create(profile_path)?.write(tmpl::PROFILES_CONFIG)?;
// }
});
let _ = dirs::app_profiles_dir().map(|profiles_dir| {
if !profiles_dir.exists() {
let _ = fs::create_dir_all(&profiles_dir);
}
});
if !clash_path.exists() {
fs::File::create(clash_path)?.write(tmpl::CLASH_CONFIG)?;
}
if !verge_path.exists() {
fs::File::create(verge_path)?.write(tmpl::VERGE_CONFIG)?;
}
if !profile_path.exists() {
fs::File::create(profile_path)?.write(tmpl::PROFILES_CONFIG)?;
}
Ok(())
}
/// initialize app
pub fn init_resources(package_info: &PackageInfo) {
// create app dir
let app_dir = dirs::app_home_dir();
let res_dir = dirs::app_resources_dir(package_info);
if !app_dir.exists() {
let _ = fs::create_dir_all(&app_dir);
}
pub fn init_resources(package_info: &PackageInfo) -> Result<()> {
let app_dir = dirs::app_home_dir()?;
let res_dir = dirs::app_resources_dir(package_info)?;
// copy the resource file
for file in ["Country.mmdb", "geoip.dat", "geosite.dat", "wintun.dll"].iter() {
@@ -99,4 +97,6 @@ pub fn init_resources(package_info: &PackageInfo) {
let _ = fs::copy(src_path, target_path);
}
}
Ok(())
}

View File

@@ -1,42 +1,5 @@
///! Some config file template
/// template for clash core `config.yaml`
pub const CLASH_CONFIG: &[u8] = br#"# Default Config For Clash Core
mixed-port: 7890
log-level: info
allow-lan: false
external-controller: 127.0.0.1:9090
mode: rule
secret: ""
"#;
/// template for `profiles.yaml`
pub const PROFILES_CONFIG: &[u8] = b"# Profiles Config for Clash Verge
current: ~
chain: ~
valid:
- dns
items: ~
";
/// template for `verge.yaml`
pub const VERGE_CONFIG: &[u8] = b"# Default Config For Clash Verge
clash_core: clash
language: en
theme_mode: system
theme_blur: false
traffic_graph: true
enable_auto_launch: false
enable_silent_start: false
enable_system_proxy: false
enable_proxy_guard: false
proxy_guard_duration: 10
auto_close_connection: true
";
/// template for new a profile item
pub const ITEM_LOCAL: &str = "# Profile Template for clash verge