Files
openfut-launcher/src/config.rs
T
funman300 fc894a7f77 feat: initial OpenFUT Launcher
GUI desktop app (egui/eframe) that manages the openfut-core and
openfut-bridge services with a single window.

- Dashboard: start/stop each service independently or together; live
  status indicators; quick-status for cert and hosts
- Logs: real-time stdout/stderr from both processes, colour-coded by
  level, follow mode and manual clear
- Setup: add/remove EA hostname redirects in /etc/hosts (pkexec/sudo);
  install the bridge TLS cert into the system CA store
- Config: all binary paths and env vars editable in-app; persisted to
  ~/.config/openfut-launcher/config.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 20:02:02 -07:00

93 lines
3.0 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LauncherConfig {
pub core_binary: String,
pub bridge_binary: String,
pub core_database_url: String,
pub core_data_dir: String,
pub core_listen_addr: String,
pub bridge_listen_addr: String,
pub bridge_captures_dir: String,
pub bridge_core_url: String,
pub bridge_tls_enabled: bool,
}
impl Default for LauncherConfig {
fn default() -> Self {
let base = dirs::home_dir()
.map(|h| h.join("Documents/OpenFUT"))
.unwrap_or_default();
Self {
core_binary: base
.join("openfut-core/target/release/openfut-core")
.to_string_lossy()
.into(),
bridge_binary: base
.join("openfut-bridge/target/release/openfut-bridge")
.to_string_lossy()
.into(),
core_database_url: "sqlite://openfut.db".into(),
core_data_dir: base
.join("openfut-core/data")
.to_string_lossy()
.into(),
core_listen_addr: "127.0.0.1:8080".into(),
bridge_listen_addr: "0.0.0.0:8765".into(),
bridge_captures_dir: base
.join("openfut-bridge/captures")
.to_string_lossy()
.into(),
bridge_core_url: "http://127.0.0.1:8080".into(),
bridge_tls_enabled: true,
}
}
}
impl LauncherConfig {
pub fn config_path() -> std::path::PathBuf {
dirs::config_dir()
.unwrap_or_else(|| std::path::PathBuf::from("."))
.join("openfut-launcher")
.join("config.json")
}
pub fn load() -> Self {
let path = Self::config_path();
std::fs::read_to_string(&path)
.ok()
.and_then(|s| serde_json::from_str(&s).ok())
.unwrap_or_default()
}
pub fn save(&self) {
let path = Self::config_path();
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
if let Ok(json) = serde_json::to_string_pretty(self) {
let _ = std::fs::write(path, json);
}
}
pub fn core_env(&self) -> Vec<(String, String)> {
vec![
("DATABASE_URL".into(), self.core_database_url.clone()),
("DATA_DIR".into(), self.core_data_dir.clone()),
("LISTEN_ADDR".into(), self.core_listen_addr.clone()),
("RUST_LOG".into(), "openfut_core=info,tower_http=info".into()),
]
}
pub fn bridge_env(&self) -> Vec<(String, String)> {
vec![
("CORE_URL".into(), self.bridge_core_url.clone()),
("LISTEN_ADDR".into(), self.bridge_listen_addr.clone()),
("CAPTURES_DIR".into(), self.bridge_captures_dir.clone()),
("TLS_ENABLED".into(), self.bridge_tls_enabled.to_string()),
("RUST_LOG".into(), "openfut_bridge=info".into()),
]
}
}