Initial commit
This commit is contained in:
75
src/config.rs
Normal file
75
src/config.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
/// Represents a single rule, capturing the URL, tag, and any other fields.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Rule {
|
||||
pub url: String,
|
||||
pub tag: String,
|
||||
// Capture any other fields in the rule object
|
||||
#[serde(flatten)]
|
||||
pub other_fields: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
/// Represents the "route" object in the config.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Route {
|
||||
#[serde(default, rename = "rule_set")]
|
||||
rule_set: Vec<Rule>,
|
||||
}
|
||||
|
||||
/// Represents the top-level structure of the configuration file.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Config {
|
||||
route: Route,
|
||||
// Capture any other top-level fields
|
||||
#[serde(flatten)]
|
||||
other_fields: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Loads and parses the config file from a given path.
|
||||
pub fn load(path: &Path) -> Result<Self> {
|
||||
let content = fs::read_to_string(path)
|
||||
.with_context(|| format!("Failed to read config file from '{}'", path.display()))?;
|
||||
let config: Config = serde_json::from_str(&content)
|
||||
.context("Failed to parse JSON. Please check the config file structure.")?;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
/// Saves the current config state back to a file, prettified.
|
||||
pub fn save(&self, path: &Path) -> Result<()> {
|
||||
let new_content = serde_json::to_string_pretty(self)
|
||||
.context("Failed to serialize modified config to JSON.")?;
|
||||
fs::write(path, new_content)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Extracts all URLs from the rule_set.
|
||||
pub fn extract_urls(&self) -> Vec<String> {
|
||||
self.route
|
||||
.rule_set
|
||||
.iter()
|
||||
.map(|rule| rule.url.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Rewrites the URLs in the config based on the provided domain and path.
|
||||
pub fn rewrite_urls(&mut self, domain: &str, rule_path: &str) -> Result<()> {
|
||||
let clean_domain = domain.trim_matches('/');
|
||||
let clean_rule_path = format!("/{}/", rule_path.trim_matches('/'));
|
||||
|
||||
for rule in &mut self.route.rule_set {
|
||||
if let Some(filename) = rule.url.split('/').last().filter(|s| !s.is_empty()) {
|
||||
let new_url = format!("https://{}{}{}", clean_domain, clean_rule_path, filename);
|
||||
println!(" '{}' -> {}", rule.tag, new_url);
|
||||
rule.url = new_url;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user