diff --git a/src-tauri/src/data/clash.rs b/src-tauri/src/data/clash.rs index 627389a3675bc94066b0f9340d2b9bb174d09717..56bbff37b557d088383847662064a81045bcc661 100644 --- a/src-tauri/src/data/clash.rs +++ b/src-tauri/src/data/clash.rs @@ -125,7 +125,7 @@ impl Clash { /// get clash config pub fn read_config() -> Mapping { - config::read_yaml::<Mapping>(dirs::clash_path()) + config::read_merge_mapping(dirs::clash_path()) } /// save the clash config diff --git a/src-tauri/src/data/prfitem.rs b/src-tauri/src/data/prfitem.rs index 2f8f69e5c025bae23f845055bd05997d6f9c5dc1..41be194e16464b910fb13f86ecf398e81480c59e 100644 --- a/src-tauri/src/data/prfitem.rs +++ b/src-tauri/src/data/prfitem.rs @@ -352,7 +352,7 @@ impl PrfItem { }), "merge" => Some(ChainItem { uid, - data: ChainType::Merge(config::read_yaml::<Mapping>(path)), + data: ChainType::Merge(config::read_merge_mapping(path)), }), _ => None, } diff --git a/src-tauri/src/data/profiles.rs b/src-tauri/src/data/profiles.rs index 6b4d6e18483af16cff875753be21305f8ae1fb56..09ac55778a4afaf0ef496ecddbf0bd655db6dd0f 100644 --- a/src-tauri/src/data/profiles.rs +++ b/src-tauri/src/data/profiles.rs @@ -283,7 +283,7 @@ impl Profiles { bail!("failed to read the file \"{}\"", file_path.display()); } - return Ok(config::read_yaml::<Mapping>(file_path.clone())); + return Ok(config::read_merge_mapping(file_path.clone())); } } bail!("failed to find current profile \"uid:{current}\""); diff --git a/src-tauri/src/utils/config.rs b/src-tauri/src/utils/config.rs index 12e3d6d3f90768ab48ab3069b1c9ef3b38c1a83b..add4d8bd40d1b0c34f18e45bb7b2ee13be7a9488 100644 --- a/src-tauri/src/utils/config.rs +++ b/src-tauri/src/utils/config.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Result}; use serde::{de::DeserializeOwned, Serialize}; +use serde_yaml::{Mapping, Value}; use std::{fs, path::PathBuf}; /// read data from yaml as struct T @@ -20,6 +21,29 @@ pub fn read_yaml<T: DeserializeOwned + Default>(path: PathBuf) -> T { } } +/// read mapping from yaml fix #165 +pub fn read_merge_mapping(path: PathBuf) -> Mapping { + let map = Mapping::new(); + + 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_if_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 + } + } +} + /// save the data to the file /// can set `prefix` string to add some comments pub fn save_yaml<T: Serialize>(path: PathBuf, data: &T, prefix: Option<&str>) -> Result<()> {