refactor: migrate from serde_yaml to serde_yaml_ng for improved YAML handling (#4568)
* refactor: migrate from serde_yaml to serde_yaml_ng for improved YAML handling * refactor: format code for better readability in DNS configuration
This commit is contained in:
committed by
GitHub
Unverified
parent
f86a1816e0
commit
3939741a06
@@ -38,5 +38,5 @@
|
||||
}
|
||||
],
|
||||
"postUpdateOptions": ["pnpmDedupe"],
|
||||
"ignoreDeps": ["serde_yaml", "criterion"]
|
||||
"ignoreDeps": ["criterion"]
|
||||
}
|
||||
|
||||
15
src-tauri/Cargo.lock
generated
15
src-tauri/Cargo.lock
generated
@@ -1127,7 +1127,7 @@ dependencies = [
|
||||
"scopeguard",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"serde_yaml_ng",
|
||||
"sha2 0.10.9",
|
||||
"sys-locale",
|
||||
"sysinfo",
|
||||
@@ -6455,6 +6455,19 @@ dependencies = [
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml_ng"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f"
|
||||
dependencies = [
|
||||
"indexmap 2.11.0",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serialize-to-javascript"
|
||||
version = "0.1.2"
|
||||
|
||||
@@ -28,7 +28,7 @@ chrono = "0.4.41"
|
||||
sysinfo = { version = "0.37.0", features = ["network", "system"] }
|
||||
boa_engine = "0.20.0"
|
||||
serde_json = "1.0.143"
|
||||
serde_yaml = "0.9.34"
|
||||
serde_yaml_ng = "0.10.0"
|
||||
once_cell = "1.21.3"
|
||||
port_scanner = "0.1.5"
|
||||
delay_timer = "0.11.6"
|
||||
@@ -83,6 +83,7 @@ isahc = { version = "1.7.2", default-features = false, features = [
|
||||
"parking_lot",
|
||||
] }
|
||||
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
runas = "=1.2.0"
|
||||
deelevate = "0.2.0"
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
utils::logging::Type,
|
||||
wrap_err,
|
||||
};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::time::Duration;
|
||||
|
||||
const CONFIG_REFRESH_INTERVAL: Duration = Duration::from_secs(60);
|
||||
@@ -143,7 +143,7 @@ pub async fn test_delay(url: String) -> CmdResult<u32> {
|
||||
#[tauri::command]
|
||||
pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
|
||||
use crate::utils::dirs;
|
||||
use serde_yaml;
|
||||
use serde_yaml_ng;
|
||||
use tokio::fs;
|
||||
|
||||
// 获取DNS配置文件路径
|
||||
@@ -152,7 +152,7 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
|
||||
.join("dns_config.yaml");
|
||||
|
||||
// 保存DNS配置到文件
|
||||
let yaml_str = serde_yaml::to_string(&dns_config).map_err(|e| e.to_string())?;
|
||||
let yaml_str = serde_yaml_ng::to_string(&dns_config).map_err(|e| e.to_string())?;
|
||||
fs::write(&dns_path, yaml_str)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
@@ -187,15 +187,16 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
|
||||
})?;
|
||||
|
||||
// 解析DNS配置
|
||||
let patch_config = serde_yaml::from_str::<serde_yaml::Mapping>(&dns_yaml).map_err(|e| {
|
||||
logging!(error, Type::Config, "Failed to parse DNS config: {e}");
|
||||
e.to_string()
|
||||
})?;
|
||||
let patch_config =
|
||||
serde_yaml_ng::from_str::<serde_yaml_ng::Mapping>(&dns_yaml).map_err(|e| {
|
||||
logging!(error, Type::Config, "Failed to parse DNS config: {e}");
|
||||
e.to_string()
|
||||
})?;
|
||||
|
||||
logging!(info, Type::Config, "Applying DNS config from file");
|
||||
|
||||
// 创建包含DNS配置的patch
|
||||
let mut patch = serde_yaml::Mapping::new();
|
||||
let mut patch = serde_yaml_ng::Mapping::new();
|
||||
patch.insert("dns".into(), patch_config.into());
|
||||
|
||||
// 应用DNS配置到运行时配置
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::core::{async_proxy_query::AsyncProxyQuery, EventDrivenProxyManager};
|
||||
use crate::process::AsyncHandler;
|
||||
use crate::wrap_err;
|
||||
use network_interface::NetworkInterface;
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
|
||||
/// get the system proxy
|
||||
#[tauri::command]
|
||||
|
||||
@@ -381,7 +381,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
match file_read_result {
|
||||
Ok(Ok(content)) => {
|
||||
let yaml_parse_result = AsyncHandler::spawn_blocking(move || {
|
||||
serde_yaml::from_str::<serde_yaml::Value>(&content)
|
||||
serde_yaml_ng::from_str::<serde_yaml_ng::Value>(&content)
|
||||
})
|
||||
.await;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::CmdResult;
|
||||
use crate::{config::*, wrap_err};
|
||||
use anyhow::Context;
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// 获取运行时配置
|
||||
@@ -19,7 +19,7 @@ pub async fn get_runtime_yaml() -> CmdResult<String> {
|
||||
wrap_err!(config
|
||||
.ok_or(anyhow::anyhow!("failed to parse config to yaml file"))
|
||||
.and_then(
|
||||
|config| serde_yaml::to_string(config).context("failed to convert config to yaml")
|
||||
|config| serde_yaml_ng::to_string(config).context("failed to convert config to yaml")
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::utils::dirs::{ipc_path, path_to_str};
|
||||
use crate::utils::{dirs, help};
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use serde_yaml_ng::{Mapping, Value};
|
||||
use std::{
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
str::FromStr,
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::utils::{
|
||||
};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::{fs, time::Duration};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||
@@ -355,7 +355,7 @@ impl PrfItem {
|
||||
let data = data.trim_start_matches('\u{feff}');
|
||||
|
||||
// check the data whether the valid yaml format
|
||||
let yaml = serde_yaml::from_str::<Mapping>(data)
|
||||
let yaml = serde_yaml_ng::from_str::<Mapping>(data)
|
||||
.context("the remote profile data is invalid yaml")?;
|
||||
|
||||
if !yaml.contains_key("proxies") && !yaml.contains_key("proxy-providers") {
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::collections::HashSet;
|
||||
use tokio::fs;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::enhance::field::use_keys;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use serde_yaml_ng::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct IRuntime {
|
||||
|
||||
@@ -264,14 +264,14 @@ pub fn create_backup() -> Result<(String, PathBuf), Error> {
|
||||
zip.write_all(fs::read(dirs::clash_path()?)?.as_slice())?;
|
||||
|
||||
let mut verge_config: serde_json::Value =
|
||||
serde_yaml::from_str(&fs::read_to_string(dirs::verge_path()?)?)?;
|
||||
serde_yaml_ng::from_str(&fs::read_to_string(dirs::verge_path()?)?)?;
|
||||
if let Some(obj) = verge_config.as_object_mut() {
|
||||
obj.remove("webdav_username");
|
||||
obj.remove("webdav_password");
|
||||
obj.remove("webdav_url");
|
||||
}
|
||||
zip.start_file(dirs::VERGE_CONFIG, options)?;
|
||||
zip.write_all(serde_yaml::to_string(&verge_config)?.as_bytes())?;
|
||||
zip.write_all(serde_yaml_ng::to_string(&verge_config)?.as_bytes())?;
|
||||
|
||||
zip.start_file(dirs::PROFILE_YAML, options)?;
|
||||
zip.write_all(fs::read(dirs::profiles_path()?)?.as_slice())?;
|
||||
|
||||
@@ -317,7 +317,7 @@ impl CoreManager {
|
||||
};
|
||||
// 对YAML文件尝试解析,只检查语法正确性
|
||||
logging!(info, Type::Config, true, "进行YAML语法检查");
|
||||
match serde_yaml::from_str::<serde_yaml::Value>(&content) {
|
||||
match serde_yaml_ng::from_str::<serde_yaml_ng::Value>(&content) {
|
||||
Ok(_) => {
|
||||
logging!(info, Type::Config, true, "YAML语法检查通过");
|
||||
Ok((true, String::new()))
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
config::PrfItem,
|
||||
utils::{dirs, help},
|
||||
};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::fs;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use serde_yaml_ng::{Mapping, Value};
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub const HANDLE_FIELDS: [&str; 12] = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::use_lowercase;
|
||||
use serde_yaml::{self, Mapping, Value};
|
||||
use serde_yaml_ng::{self, Mapping, Value};
|
||||
|
||||
fn deep_merge(a: &mut Value, b: &Value) {
|
||||
match (a, b) {
|
||||
@@ -54,10 +54,10 @@ fn test_merge() -> anyhow::Result<()> {
|
||||
script1: test
|
||||
";
|
||||
|
||||
let merge = serde_yaml::from_str::<Mapping>(merge)?;
|
||||
let config = serde_yaml::from_str::<Mapping>(config)?;
|
||||
let merge = serde_yaml_ng::from_str::<Mapping>(merge)?;
|
||||
let config = serde_yaml_ng::from_str::<Mapping>(config)?;
|
||||
|
||||
let _ = serde_yaml::to_string(&use_merge(merge, config))?;
|
||||
let _ = serde_yaml_ng::to_string(&use_merge(merge, config))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ mod tun;
|
||||
|
||||
use self::{chain::*, field::*, merge::*, script::*, seq::*, tun::*};
|
||||
use crate::{config::Config, utils::tmpl};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
type ResultLog = Vec<(String, String)>;
|
||||
@@ -386,7 +386,9 @@ pub async fn enhance() -> (Mapping, Vec<String>, HashMap<String, ResultLog>) {
|
||||
|
||||
if dns_path.exists() {
|
||||
if let Ok(dns_yaml) = fs::read_to_string(&dns_path) {
|
||||
if let Ok(dns_config) = serde_yaml::from_str::<serde_yaml::Mapping>(&dns_yaml) {
|
||||
if let Ok(dns_config) =
|
||||
serde_yaml_ng::from_str::<serde_yaml_ng::Mapping>(&dns_yaml)
|
||||
{
|
||||
// 处理hosts配置
|
||||
if let Some(hosts_value) = dns_config.get("hosts") {
|
||||
if hosts_value.is_mapping() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::use_lowercase;
|
||||
use anyhow::{Error, Result};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
|
||||
pub fn use_script(
|
||||
script: String,
|
||||
@@ -149,11 +149,11 @@ fn test_script() {
|
||||
enable: false
|
||||
";
|
||||
|
||||
let config = serde_yaml::from_str(config).expect("Failed to parse test config YAML");
|
||||
let config = serde_yaml_ng::from_str(config).expect("Failed to parse test config YAML");
|
||||
let (config, results) = use_script(script.into(), config, "".to_string())
|
||||
.expect("Script execution should succeed in test");
|
||||
|
||||
let _ = serde_yaml::to_string(&config).expect("Failed to serialize config to YAML");
|
||||
let _ = serde_yaml_ng::to_string(&config).expect("Failed to serialize config to YAML");
|
||||
let yaml_config_size = std::mem::size_of_val(&config);
|
||||
let box_yaml_config_size = std::mem::size_of_val(&Box::new(config));
|
||||
assert!(box_yaml_config_size < yaml_config_size);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Sequence, Value};
|
||||
use serde_yaml_ng::{Mapping, Sequence, Value};
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct SeqMap {
|
||||
@@ -86,7 +86,7 @@ pub fn use_seq(seq: SeqMap, mut config: Mapping, field: &str) -> Mapping {
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[allow(unused_imports)]
|
||||
use serde_yaml::Value;
|
||||
use serde_yaml_ng::Value;
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unwrap_used)]
|
||||
@@ -110,7 +110,7 @@ proxy-groups:
|
||||
- "proxy1"
|
||||
"#;
|
||||
let mut config: Mapping =
|
||||
serde_yaml::from_str(config_str).expect("Failed to parse test config YAML");
|
||||
serde_yaml_ng::from_str(config_str).expect("Failed to parse test config YAML");
|
||||
|
||||
let seq = SeqMap {
|
||||
prepend: Sequence::new(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use serde_yaml_ng::{Mapping, Value};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::process::AsyncHandler;
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
process::AsyncHandler,
|
||||
utils::{logging::Type, resolve},
|
||||
};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use serde_yaml_ng::{Mapping, Value};
|
||||
|
||||
/// Restart the Clash core
|
||||
pub async fn restart_clash_core() {
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
utils::logging::Type,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
|
||||
/// Patch Clash configuration
|
||||
pub async fn patch_clash(patch: Mapping) -> Result<()> {
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{enhance::seq::SeqMap, logging, utils::logging::Type};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use nanoid::nanoid;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use serde_yaml_ng::Mapping;
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
/// read data from yaml as struct T
|
||||
@@ -13,7 +13,7 @@ pub async fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
|
||||
|
||||
let yaml_str = tokio::fs::read_to_string(path).await?;
|
||||
|
||||
Ok(serde_yaml::from_str::<T>(&yaml_str)?)
|
||||
Ok(serde_yaml_ng::from_str::<T>(&yaml_str)?)
|
||||
}
|
||||
|
||||
/// read mapping from yaml
|
||||
@@ -27,7 +27,7 @@ pub async fn read_mapping(path: &PathBuf) -> Result<Mapping> {
|
||||
.with_context(|| format!("failed to read the file \"{}\"", path.display()))?;
|
||||
|
||||
// YAML语法检查
|
||||
match serde_yaml::from_str::<serde_yaml::Value>(&yaml_str) {
|
||||
match serde_yaml_ng::from_str::<serde_yaml_ng::Value>(&yaml_str) {
|
||||
Ok(mut val) => {
|
||||
val.apply_merge()
|
||||
.with_context(|| format!("failed to apply merge \"{}\"", path.display()))?;
|
||||
@@ -66,7 +66,7 @@ pub async fn save_yaml<T: Serialize + Sync>(
|
||||
data: &T,
|
||||
prefix: Option<&str>,
|
||||
) -> Result<()> {
|
||||
let data_str = serde_yaml::to_string(data)?;
|
||||
let data_str = serde_yaml_ng::to_string(data)?;
|
||||
|
||||
let yaml_str = match prefix {
|
||||
Some(prefix) => format!("{prefix}\n\n{data_str}"),
|
||||
|
||||
@@ -142,10 +142,10 @@ pub async fn delete_log() -> Result<()> {
|
||||
|
||||
/// 初始化DNS配置文件
|
||||
async fn init_dns_config() -> Result<()> {
|
||||
use serde_yaml::Value;
|
||||
use serde_yaml_ng::Value;
|
||||
|
||||
// 创建DNS子配置
|
||||
let dns_config = serde_yaml::Mapping::from_iter([
|
||||
let dns_config = serde_yaml_ng::Mapping::from_iter([
|
||||
("enable".into(), Value::Bool(true)),
|
||||
("listen".into(), Value::String(":53".into())),
|
||||
("enhanced-mode".into(), Value::String("fake-ip".into())),
|
||||
@@ -197,7 +197,7 @@ async fn init_dns_config() -> Result<()> {
|
||||
("fallback".into(), Value::Sequence(vec![])),
|
||||
(
|
||||
"nameserver-policy".into(),
|
||||
Value::Mapping(serde_yaml::Mapping::new()),
|
||||
Value::Mapping(serde_yaml_ng::Mapping::new()),
|
||||
),
|
||||
(
|
||||
"proxy-server-nameserver".into(),
|
||||
@@ -211,7 +211,7 @@ async fn init_dns_config() -> Result<()> {
|
||||
("direct-nameserver-follow-policy".into(), Value::Bool(false)),
|
||||
(
|
||||
"fallback-filter".into(),
|
||||
Value::Mapping(serde_yaml::Mapping::from_iter([
|
||||
Value::Mapping(serde_yaml_ng::Mapping::from_iter([
|
||||
("geoip".into(), Value::Bool(true)),
|
||||
("geoip-code".into(), Value::String("CN".into())),
|
||||
(
|
||||
@@ -234,9 +234,12 @@ async fn init_dns_config() -> Result<()> {
|
||||
]);
|
||||
|
||||
// 获取默认DNS和host配置
|
||||
let default_dns_config = serde_yaml::Mapping::from_iter([
|
||||
let default_dns_config = serde_yaml_ng::Mapping::from_iter([
|
||||
("dns".into(), Value::Mapping(dns_config)),
|
||||
("hosts".into(), Value::Mapping(serde_yaml::Mapping::new())),
|
||||
(
|
||||
"hosts".into(),
|
||||
Value::Mapping(serde_yaml_ng::Mapping::new()),
|
||||
),
|
||||
]);
|
||||
|
||||
// 检查DNS配置文件是否存在
|
||||
|
||||
Reference in New Issue
Block a user