use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Proxy {
pub remote: String,
pub bind: String,
pub protocol: String,
}
fn default_max_connections() -> usize { 1024 }
fn default_max_client_tunnels() -> usize { 1024 }
fn default_keepalive_idle() -> u64 { 60 }
fn default_keepalive_interval() -> u64 { 30 }
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Settings {
#[serde(default = "default_max_connections")]
pub max_connections: usize,
#[serde(default = "default_max_client_tunnels")]
pub max_client_tunnels: usize,
#[serde(default = "default_keepalive_idle")]
pub keepalive_idle: u64,
#[serde(default = "default_keepalive_interval")]
pub keepalive_interval: u64,
}
impl Default for Settings {
fn default() -> Self {
Settings {
max_connections: default_max_connections(),
max_client_tunnels: default_max_client_tunnels(),
keepalive_idle: default_keepalive_idle(),
keepalive_interval: default_keepalive_interval(),
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Config {
#[serde(default)]
pub settings: Settings,
pub proxies: Vec<Proxy>,
}
pub fn load_config(path: &Path) -> Result<Config, Box<dyn std::error::Error>> {
let content = std::fs::read_to_string(path)?;
let content = content.strip_prefix('\u{feff}').unwrap_or(&content);
if let Ok(config) = serde_json::from_str::<Config>(content) {
Ok(config)
} else {
let proxies: Vec<Proxy> = serde_json::from_str(content)?;
let config = Config {
settings: Settings::default(),
proxies,
};
if let Ok(json) = serde_json::to_string_pretty(&config) {
let _ = std::fs::write(path, json);
}
Ok(config)
}
}
pub fn save_config(path: &Path, config: &Config) -> Result<(), Box<dyn std::error::Error>> {
let json = serde_json::to_string_pretty(config)?;
std::fs::write(path, json)?;
Ok(())
}