132 lines
3.4 KiB
Rust
132 lines
3.4 KiB
Rust
use std::{fs, io, path::PathBuf};
|
|
|
|
use super::paths;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Config {
|
|
pub base_url: String,
|
|
pub access_token: Option<String>,
|
|
pub user_id: Option<String>,
|
|
pub transcode_mbps: Option<u32>,
|
|
pub transcode_default_on: Option<bool>,
|
|
}
|
|
|
|
|
|
#[derive(Debug)]
|
|
pub enum ConfigError {
|
|
NotFound(PathBuf),
|
|
Io(io::Error),
|
|
Parse(String),
|
|
}
|
|
|
|
impl From<io::Error> for ConfigError {
|
|
fn from(e: io::Error) -> Self {
|
|
Self::Io(e)
|
|
}
|
|
}
|
|
|
|
pub fn config_path() -> Option<PathBuf> {
|
|
paths::app_config_dir().map(|d| d.join("config.toml"))
|
|
}
|
|
|
|
// Very small TOML-ish parser for now (no deps).
|
|
// Format:
|
|
// base_url = "http://..."
|
|
// access_token = "..."
|
|
pub fn load_config() -> Result<Config, ConfigError> {
|
|
let path = config_path().ok_or_else(|| ConfigError::Parse("No HOME/XDG dirs".into()))?;
|
|
if !path.exists() {
|
|
return Err(ConfigError::NotFound(path));
|
|
}
|
|
|
|
let s = fs::read_to_string(&path)?;
|
|
parse_config(&s).map_err(ConfigError::Parse)
|
|
}
|
|
|
|
fn parse_config(s: &str) -> Result<Config, String> {
|
|
let mut base_url: Option<String> = None;
|
|
let mut access_token: Option<String> = None;
|
|
let mut user_id: Option<String> = None;
|
|
let mut transcode_mbps: Option<u32> = None;
|
|
let mut transcode_default_on: Option<bool> = None;
|
|
|
|
for (i, line) in s.lines().enumerate() {
|
|
let line = line.trim();
|
|
if line.is_empty() || line.starts_with('#') {
|
|
continue;
|
|
}
|
|
|
|
let (k, v) = line
|
|
.split_once('=')
|
|
.ok_or_else(|| format!("Line {}: expected key = value", i + 1))?;
|
|
|
|
let key = k.trim();
|
|
let mut val = v.trim().to_string();
|
|
|
|
// strip quotes if present
|
|
if val.starts_with('"') && val.ends_with('"') && val.len() >= 2 {
|
|
val = val[1..val.len() - 1].to_string();
|
|
}
|
|
|
|
match key {
|
|
"base_url" => base_url = Some(val),
|
|
"access_token" => access_token = Some(val),
|
|
"user_id" => user_id = Some(val),
|
|
|
|
"transcode_mbps" => {
|
|
transcode_mbps = val.parse::<u32>().ok();
|
|
}
|
|
|
|
"transcode_default_on" => {
|
|
transcode_default_on = match val.as_str() {
|
|
"true" => Some(true),
|
|
"false" => Some(false),
|
|
_ => None,
|
|
};
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
let base_url = base_url.ok_or_else(|| "Missing base_url".to_string())?;
|
|
|
|
Ok(Config {
|
|
base_url,
|
|
access_token,
|
|
user_id,
|
|
transcode_mbps,
|
|
transcode_default_on,
|
|
})
|
|
}
|
|
|
|
pub fn save_config(cfg: &Config) -> Result<(), ConfigError> {
|
|
let dir = paths::app_config_dir()
|
|
.ok_or_else(|| ConfigError::Parse("No HOME/XDG dirs".into()))?;
|
|
std::fs::create_dir_all(&dir)?;
|
|
|
|
let path = dir.join("config.toml");
|
|
|
|
let mut out = String::new();
|
|
|
|
out.push_str(&format!("base_url = \"{}\"\n", cfg.base_url));
|
|
|
|
if let Some(t) = &cfg.access_token {
|
|
out.push_str(&format!("access_token = \"{}\"\n", t));
|
|
}
|
|
|
|
if let Some(u) = &cfg.user_id {
|
|
out.push_str(&format!("user_id = \"{}\"\n", u));
|
|
}
|
|
|
|
if let Some(m) = cfg.transcode_mbps {
|
|
out.push_str(&format!("transcode_mbps = {}\n", m));
|
|
}
|
|
|
|
if let Some(b) = cfg.transcode_default_on {
|
|
out.push_str(&format!("transcode_default_on = {}\n", b));
|
|
}
|
|
|
|
std::fs::write(path, out)?;
|
|
Ok(())
|
|
}
|