use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RulesetType {
Surge,
Quanx,
ClashDomain,
ClashIpcidr,
ClashClassical,
}
impl Default for RulesetType {
fn default() -> Self {
RulesetType::Surge
}
}
pub type RulesetMapping = HashMap<String, RulesetType>;
pub static RULESET_TYPES: once_cell::sync::Lazy<RulesetMapping> =
once_cell::sync::Lazy::new(|| {
let mut types = RulesetMapping::new();
types.insert("clash-domain:".to_string(), RulesetType::ClashDomain);
types.insert("clash-ipcidr:".to_string(), RulesetType::ClashIpcidr);
types.insert("clash-classical:".to_string(), RulesetType::ClashClassical);
types.insert("quanx:".to_string(), RulesetType::Quanx);
types.insert("surge:".to_string(), RulesetType::Surge);
types
});
pub fn get_ruleset_type_from_url(url: &str) -> Option<RulesetType> {
for (prefix, ruleset_type) in RULESET_TYPES.iter() {
if url.starts_with(prefix) {
return Some(ruleset_type.clone());
}
}
None
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct RulesetConfig {
pub group: String,
pub url: String,
pub interval: u32,
}
pub type RulesetConfigs = Vec<RulesetConfig>;
#[derive(Debug, Clone)]
pub struct RulesetContent {
pub group: String, pub rule_path: String, pub rule_path_typed: String, pub rule_type: RulesetType,
pub rule_content: Arc<RwLock<Option<String>>>,
pub update_interval: u32, }
impl RulesetContent {
pub fn new(rule_path: &str, group: &str) -> Self {
RulesetContent {
group: group.to_string(),
rule_path: rule_path.to_string(),
rule_path_typed: rule_path.to_string(),
rule_type: RulesetType::default(),
rule_content: Arc::new(RwLock::new(None)),
update_interval: 0,
}
}
pub fn get_rule_content(&self) -> String {
match self.rule_content.read() {
Ok(guard) => match &*guard {
Some(content) => content.clone(),
None => String::new(),
},
Err(_) => String::new(),
}
}
pub fn set_rule_content(&mut self, content: &str) {
if let Ok(mut guard) = self.rule_content.write() {
*guard = Some(content.to_string());
}
}
pub fn has_rule_content(&self) -> bool {
match self.rule_content.read() {
Ok(guard) => guard.is_some(),
Err(_) => false,
}
}
}
pub fn parse_ruleset(content: &str, group: &str) -> RulesetContent {
let mut ruleset = RulesetContent::new("", group);
ruleset.set_rule_content(content);
ruleset
}