refactor: done

This commit is contained in:
GyDi
2022-11-18 18:18:41 +08:00
parent 34daffbc96
commit 2667ed13f1
24 changed files with 343 additions and 341 deletions

View File

@@ -1,4 +1,4 @@
use crate::utils::{config, dirs};
use crate::utils::{dirs, help};
use anyhow::Result;
use serde::{Deserialize, Serialize};
use serde_yaml::{Mapping, Value};
@@ -8,7 +8,7 @@ pub struct IClashTemp(pub Mapping);
impl IClashTemp {
pub fn new() -> Self {
match dirs::clash_path().and_then(|path| config::read_merge_mapping(&path)) {
match dirs::clash_path().and_then(|path| help::read_merge_mapping(&path)) {
Ok(map) => Self(map),
Err(err) => {
log::error!(target: "app", "{err}");
@@ -20,7 +20,7 @@ impl IClashTemp {
pub fn template() -> Self {
let mut map = Mapping::new();
map.insert("mixed-port".into(), 7892.into());
map.insert("mixed-port".into(), 7890.into());
map.insert("log-level".into(), "info".into());
map.insert("allow-lan".into(), false.into());
map.insert("mode".into(), "rule".into());
@@ -37,10 +37,10 @@ impl IClashTemp {
}
pub fn save_config(&self) -> Result<()> {
config::save_yaml(
dirs::clash_path()?,
help::save_yaml(
&dirs::clash_path()?,
&self.0,
Some("# Default Config For ClashN Core\n\n"),
Some("# Generated by Clash Verge"),
)
}

View File

@@ -1,10 +1,20 @@
use super::{Draft, IClashTemp, IProfiles, IVerge};
use super::{Draft, IClashTemp, IProfiles, IRuntime, IVerge};
use crate::{
enhance,
utils::{dirs, help},
};
use anyhow::{anyhow, Result};
use once_cell::sync::OnceCell;
use std::{env::temp_dir, path::PathBuf};
pub const RUNTIME_CONFIG: &str = "clash-verge.yaml";
pub const CHECK_CONFIG: &str = "clash-verge-check.yaml";
pub struct Config {
clash_config: Draft<IClashTemp>,
verge_config: Draft<IVerge>,
profiles_config: Draft<IProfiles>,
runtime_config: Draft<IRuntime>,
}
impl Config {
@@ -15,6 +25,7 @@ impl Config {
clash_config: Draft::from(IClashTemp::new()),
verge_config: Draft::from(IVerge::new()),
profiles_config: Draft::from(IProfiles::new()),
runtime_config: Draft::from(IRuntime::new()),
})
}
@@ -29,4 +40,72 @@ impl Config {
pub fn profiles() -> Draft<IProfiles> {
Self::global().profiles_config.clone()
}
pub fn runtime() -> Draft<IRuntime> {
Self::global().runtime_config.clone()
}
/// 初始化配置
pub fn init_config() -> Result<()> {
crate::log_err!(Self::generate());
if let Err(err) = Self::generate_file(ConfigType::Run) {
log::error!(target: "app", "{err}");
let runtime_path = dirs::app_home_dir()?.join(RUNTIME_CONFIG);
// 如果不存在就将默认的clash文件拿过来
if !runtime_path.exists() {
help::save_yaml(
&runtime_path,
&Config::clash().latest().0,
Some("# Clash Verge Runtime"),
)?;
}
}
Ok(())
}
/// 将配置丢到对应的文件中
pub fn generate_file(typ: ConfigType) -> Result<PathBuf> {
let path = match typ {
ConfigType::Run => dirs::app_home_dir()?.join(RUNTIME_CONFIG),
ConfigType::Check => temp_dir().join(CHECK_CONFIG),
};
let runtime = Config::runtime();
let runtime = runtime.latest();
let config = runtime
.config
.as_ref()
.ok_or(anyhow!("failed to get runtime config"))?;
help::save_yaml(&path, &config, Some("# Generated by Clash Verge"))?;
Ok(path)
}
/// 生成配置存好
pub fn generate() -> Result<()> {
let clash_config = { Config::clash().latest().clone() };
let tun_mode = { Config::verge().latest().enable_tun_mode.clone() };
let tun_mode = tun_mode.unwrap_or(false);
let pa = { Config::profiles().latest().gen_activate()? };
let (config, exists_keys, logs) =
enhance::enhance_config(clash_config.0, pa.current, pa.chain, pa.valid, tun_mode);
*Config::runtime().draft() = IRuntime {
config: Some(config),
exists_keys,
chain_logs: logs,
};
Ok(())
}
}
#[derive(Debug)]
pub enum ConfigType {
Run,
Check,
}

View File

@@ -1,4 +1,4 @@
use super::{IClashTemp, IProfiles, IVerge};
use super::{IClashTemp, IProfiles, IRuntime, IVerge};
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
use std::sync::Arc;
@@ -10,6 +10,7 @@ pub struct Draft<T: Clone + ToOwned> {
macro_rules! draft_define {
($id: ident) => {
impl Draft<$id> {
#[allow(unused)]
pub fn data(&self) -> MappedMutexGuard<$id> {
MutexGuard::map(self.inner.lock(), |guard| &mut guard.0)
}
@@ -65,9 +66,9 @@ macro_rules! draft_define {
// draft_define!(IClash);
draft_define!(IClashTemp);
draft_define!(IVerge);
// draft_define!(Mapping);
draft_define!(IProfiles);
draft_define!(IRuntime);
draft_define!(IVerge);
#[test]
fn test_draft() {

View File

@@ -3,6 +3,7 @@ mod config;
mod draft;
mod prfitem;
mod profiles;
mod runtime;
mod verge;
pub use self::clash::*;
@@ -10,4 +11,5 @@ pub use self::config::*;
pub use self::draft::*;
pub use self::prfitem::*;
pub use self::profiles::*;
pub use self::runtime::*;
pub use self::verge::*;

View File

@@ -1,4 +1,4 @@
use crate::utils::{config, dirs, help, tmpl};
use crate::utils::{dirs, help, tmpl};
use anyhow::{bail, Context, Result};
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
@@ -388,7 +388,7 @@ impl PrfItem {
}),
"merge" => Some(ChainItem {
uid,
data: ChainType::Merge(config::read_merge_mapping(&path).ok()?),
data: ChainType::Merge(help::read_merge_mapping(&path).ok()?),
}),
_ => None,
}

View File

@@ -1,9 +1,8 @@
use super::{prfitem::PrfItem, ChainItem};
use crate::utils::{config, dirs, help};
use crate::utils::{dirs, help};
use anyhow::{bail, Context, Result};
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use std::collections::HashMap;
use std::{fs, io::Write};
/// Define the `profiles.yaml` schema
@@ -32,7 +31,7 @@ macro_rules! patch {
impl IProfiles {
pub fn new() -> Self {
match dirs::profiles_path().and_then(|path| config::read_yaml::<Self>(&path)) {
match dirs::profiles_path().and_then(|path| help::read_yaml::<Self>(&path)) {
Ok(mut profiles) => {
if profiles.items.is_none() {
profiles.items = Some(vec![]);
@@ -62,21 +61,45 @@ impl IProfiles {
}
}
/// save the config to the file
pub fn save_file(&self) -> Result<()> {
config::save_yaml(
dirs::profiles_path()?,
help::save_yaml(
&dirs::profiles_path()?,
self,
Some("# Profiles Config for Clash Verge\n\n"),
Some("# Profiles Config for Clash Verge"),
)
}
/// get the current uid
/// 只修改currentvalid和chain
pub fn patch_config(&mut self, patch: IProfiles) -> Result<()> {
if self.items.is_none() {
self.items = Some(vec![]);
}
if let Some(current) = patch.current {
let items = self.items.as_ref().unwrap();
let some_uid = Some(current);
if items.iter().any(|e| e.uid == some_uid) {
self.current = some_uid;
}
}
if let Some(chain) = patch.chain {
self.chain = Some(chain);
}
if let Some(valid) = patch.valid {
self.valid = Some(valid);
}
Ok(())
}
pub fn get_current(&self) -> Option<String> {
self.current.clone()
}
/// only change the main to the target id
#[deprecated]
pub fn put_current(&mut self, uid: String) -> Result<()> {
if self.items.is_none() {
self.items = Some(vec![]);
@@ -93,13 +116,13 @@ impl IProfiles {
bail!("invalid uid \"{uid}\"");
}
/// just change the `chain`
#[deprecated]
pub fn put_chain(&mut self, chain: Option<Vec<String>>) -> Result<()> {
self.chain = chain;
self.save_file()
}
/// just change the `field`
#[deprecated]
pub fn put_valid(&mut self, valid: Option<Vec<String>>) -> Result<()> {
self.valid = valid;
self.save_file()
@@ -283,7 +306,7 @@ impl IProfiles {
None => bail!("failed to get the file field"),
};
return Ok(config::read_merge_mapping(&file_path)?);
return Ok(help::read_merge_mapping(&file_path)?);
}
}
bail!("failed to find the current profile \"uid:{current}\"");
@@ -316,13 +339,3 @@ pub struct PrfActivate {
pub chain: Vec<ChainItem>,
pub valid: Vec<String>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct RuntimeResult {
pub config: Option<Mapping>,
pub config_yaml: Option<String>,
// 记录在配置中包括merge和script生成的出现过的keys
// 这些keys不一定都生效
pub exists_keys: Vec<String>,
pub chain_logs: HashMap<String, Vec<(String, String)>>,
}

View File

@@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use std::collections::HashMap;
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IRuntime {
pub config: Option<Mapping>,
// 记录在配置中包括merge和script生成的出现过的keys
// 这些keys不一定都生效
pub exists_keys: Vec<String>,
pub chain_logs: HashMap<String, Vec<(String, String)>>,
}
impl IRuntime {
pub fn new() -> Self {
Self::default()
}
}

View File

@@ -1,4 +1,4 @@
use crate::utils::{config, dirs};
use crate::utils::{dirs, help};
use anyhow::Result;
use serde::{Deserialize, Serialize};
@@ -85,7 +85,7 @@ pub struct IVergeTheme {
impl IVerge {
pub fn new() -> Self {
match dirs::verge_path().and_then(|path| config::read_yaml::<IVerge>(&path)) {
match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
Ok(config) => config,
Err(err) => {
log::error!(target: "app", "{err}");
@@ -113,11 +113,7 @@ impl IVerge {
/// Save IVerge App Config
pub fn save_file(&self) -> Result<()> {
config::save_yaml(
dirs::verge_path()?,
&self,
Some("# The Config for Clash IVerge App\n\n"),
)
help::save_yaml(&dirs::verge_path()?, &self, Some("# Clash Verge Config"))
}
/// patch verge config
@@ -161,7 +157,7 @@ impl IVerge {
#[cfg(feature = "verge-dev")]
const SERVER_PORT: u16 = 11233;
match dirs::verge_path().and_then(|path| config::read_yaml::<IVerge>(&path)) {
match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
Ok(config) => config.app_singleton_port.unwrap_or(SERVER_PORT),
Err(_) => SERVER_PORT, // 这里就不log错误了
}