mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-04-17 07:50:33 +08:00
perf: add PartialEq derive to PrfSelected and PrfExtra structs for improved comparison
This commit is contained in:
parent
a5bfe5f377
commit
6ee27bfe50
@ -60,13 +60,13 @@ pub struct PrfItem {
|
|||||||
pub file_data: Option<String>,
|
pub file_data: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct PrfSelected {
|
pub struct PrfSelected {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub now: Option<String>,
|
pub now: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Copy, Deserialize, Serialize)]
|
#[derive(Default, Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct PrfExtra {
|
pub struct PrfExtra {
|
||||||
pub upload: u64,
|
pub upload: u64,
|
||||||
pub download: u64,
|
pub download: u64,
|
||||||
|
|||||||
@ -37,8 +37,10 @@ pub struct CleanupResult {
|
|||||||
|
|
||||||
macro_rules! patch {
|
macro_rules! patch {
|
||||||
($lv: expr, $rv: expr, $key: tt) => {
|
($lv: expr, $rv: expr, $key: tt) => {
|
||||||
if ($rv.$key).is_some() {
|
if let Some(ref val) = $rv.$key {
|
||||||
$lv.$key = $rv.$key.to_owned();
|
if Some(val) != $lv.$key.as_ref() {
|
||||||
|
$lv.$key = Some(val.to_owned());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -53,21 +55,22 @@ impl IProfiles {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match help::read_yaml::<Self>(&path).await {
|
let mut profiles = match help::read_yaml::<Self>(&path).await {
|
||||||
Ok(mut profiles) => {
|
Ok(profiles) => profiles,
|
||||||
let items = profiles.items.get_or_insert_with(Vec::new);
|
|
||||||
for item in items.iter_mut() {
|
|
||||||
if item.uid.is_none() {
|
|
||||||
item.uid = Some(help::get_uid("d").into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
profiles
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
logging!(error, Type::Config, "{err}");
|
logging!(error, Type::Config, "{err}");
|
||||||
Self::default()
|
return Self::default();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let items = profiles.items.get_or_insert_with(Vec::new);
|
||||||
|
for item in items.iter_mut() {
|
||||||
|
if item.uid.is_none() {
|
||||||
|
item.uid = Some(help::get_uid("d").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profiles
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn save_file(&self) -> Result<()> {
|
pub async fn save_file(&self) -> Result<()> {
|
||||||
@ -103,38 +106,28 @@ impl IProfiles {
|
|||||||
pub fn get_item(&self, uid: impl AsRef<str>) -> Result<&PrfItem> {
|
pub fn get_item(&self, uid: impl AsRef<str>) -> Result<&PrfItem> {
|
||||||
let uid_str = uid.as_ref();
|
let uid_str = uid.as_ref();
|
||||||
|
|
||||||
if let Some(items) = self.items.as_ref() {
|
self.items
|
||||||
for each in items.iter() {
|
.as_ref()
|
||||||
if let Some(uid_val) = &each.uid
|
.ok_or_else(|| anyhow::anyhow!("no profile items found"))?
|
||||||
&& uid_val.as_str() == uid_str
|
.iter()
|
||||||
{
|
.find(|each| each.uid.as_ref().is_some_and(|uid_val| uid_val.as_str() == uid_str))
|
||||||
return Ok(each);
|
.ok_or_else(|| anyhow::anyhow!("failed to get the profile item \"uid:{}\"", uid_str))
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bail!("failed to get the profile item \"uid:{}\"", uid_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// append new item
|
/// append new item
|
||||||
/// if the file_data is some
|
/// if the file_data is some
|
||||||
/// then should save the data to file
|
/// then should save the data to file
|
||||||
pub async fn append_item(&mut self, item: &mut PrfItem) -> Result<()> {
|
pub async fn append_item(&mut self, item: &mut PrfItem) -> Result<()> {
|
||||||
let uid = &item.uid;
|
anyhow::ensure!(item.uid.is_some(), "the uid should not be null");
|
||||||
if uid.is_none() {
|
|
||||||
bail!("the uid should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
// save the file data
|
// save the file data
|
||||||
// move the field value after save
|
// move the field value after save
|
||||||
if let Some(file_data) = item.file_data.take() {
|
if let Some(file_data) = item.file_data.take() {
|
||||||
if item.file.is_none() {
|
anyhow::ensure!(item.file.is_some(), "the file should not be null");
|
||||||
bail!("the file should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
let file = item
|
let file = item
|
||||||
.file
|
.file
|
||||||
.clone()
|
.as_ref()
|
||||||
.ok_or_else(|| anyhow::anyhow!("file field is required when file_data is provided"))?;
|
.ok_or_else(|| anyhow::anyhow!("file field is required when file_data is provided"))?;
|
||||||
let path = dirs::app_profiles_dir()?.join(file.as_str());
|
let path = dirs::app_profiles_dir()?.join(file.as_str());
|
||||||
|
|
||||||
@ -143,17 +136,14 @@ impl IProfiles {
|
|||||||
.with_context(|| format!("failed to write to file \"{file}\""))?;
|
.with_context(|| format!("failed to write to file \"{file}\""))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.current.is_none() && (item.itype == Some("remote".into()) || item.itype == Some("local".into())) {
|
if self.current.is_none()
|
||||||
self.current = uid.to_owned();
|
&& let Some(t) = item.itype.as_deref()
|
||||||
|
&& (t == "remote" || t == "local")
|
||||||
|
{
|
||||||
|
self.current = item.uid.to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.items.is_none() {
|
self.items.get_or_insert_default().push(std::mem::take(item));
|
||||||
self.items = Some(vec![]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(items) = self.items.as_mut() {
|
|
||||||
items.push(item.to_owned());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -200,26 +190,27 @@ impl IProfiles {
|
|||||||
|
|
||||||
/// update the item value
|
/// update the item value
|
||||||
pub async fn patch_item(&mut self, uid: &String, item: &PrfItem) -> Result<()> {
|
pub async fn patch_item(&mut self, uid: &String, item: &PrfItem) -> Result<()> {
|
||||||
let mut items = self.items.take().unwrap_or_default();
|
let items = self
|
||||||
|
.items
|
||||||
|
.as_mut()
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("no profile items found"))?;
|
||||||
|
|
||||||
for each in items.iter_mut() {
|
let target = items.iter_mut().find(|each| each.uid.as_ref() == Some(uid));
|
||||||
if each.uid.as_ref() == Some(uid) {
|
|
||||||
patch!(each, item, itype);
|
|
||||||
patch!(each, item, name);
|
|
||||||
patch!(each, item, desc);
|
|
||||||
patch!(each, item, file);
|
|
||||||
patch!(each, item, url);
|
|
||||||
patch!(each, item, selected);
|
|
||||||
patch!(each, item, extra);
|
|
||||||
patch!(each, item, updated);
|
|
||||||
patch!(each, item, option);
|
|
||||||
|
|
||||||
self.items = Some(items);
|
if let Some(each) = target {
|
||||||
return self.save_file().await;
|
patch!(each, item, itype);
|
||||||
}
|
patch!(each, item, name);
|
||||||
|
patch!(each, item, desc);
|
||||||
|
patch!(each, item, file);
|
||||||
|
patch!(each, item, url);
|
||||||
|
patch!(each, item, selected);
|
||||||
|
patch!(each, item, extra);
|
||||||
|
patch!(each, item, updated);
|
||||||
|
patch!(each, item, option);
|
||||||
|
|
||||||
|
return self.save_file().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.items = Some(items);
|
|
||||||
bail!("failed to find the profile item \"uid:{uid}\"")
|
bail!("failed to find the profile item \"uid:{uid}\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@ pub struct TimerTask {
|
|||||||
pub last_run: i64, // Timestamp of last execution
|
pub last_run: i64, // Timestamp of last execution
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO 一个 Timer 负责轻量, 一个 Timer 负责订阅更新。当前会生产 N(订阅数量) + 1 个定时任务
|
||||||
pub struct Timer {
|
pub struct Timer {
|
||||||
/// cron manager
|
/// cron manager
|
||||||
pub delay_timer: Arc<RwLock<DelayTimer>>,
|
pub delay_timer: Arc<RwLock<DelayTimer>>,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user