feat(core): add persisted app config model
test / workspace (push) Successful in 12m6s

This commit is contained in:
Tom You
2026-07-06 23:54:33 -05:00
parent 21cbcde7bd
commit 9a61ff4a79
2 changed files with 86 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
use crate::{ConnectionKind, Profile};
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ShortcutBinding {
pub command: String,
pub binding: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AppConfig {
pub profiles: Vec<Profile>,
pub theme_id: String,
pub shortcuts: Vec<ShortcutBinding>,
pub restore_workspace: bool,
}
impl AppConfig {
pub fn default_linux() -> Self {
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/bash".to_string());
Self {
profiles: vec![Profile::new(
"local",
"Local Shell",
ConnectionKind::LocalShell,
&shell,
)
.expect("default local profile is valid")],
theme_id: "rabby-dark".to_string(),
shortcuts: Vec::new(),
restore_workspace: true,
}
}
pub fn validate(&self) -> Result<(), String> {
if self.theme_id.trim().is_empty() {
return Err("theme id is required".to_string());
}
let mut profile_ids = HashSet::new();
for profile in &self.profiles {
if !profile_ids.insert(profile.id.as_str()) {
return Err(format!("duplicate profile id: {}", profile.id));
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{ConnectionKind, Profile};
#[test]
fn default_config_includes_local_shell_profile() {
let config = AppConfig::default_linux();
assert_eq!(config.theme_id, "rabby-dark");
assert!(config.restore_workspace);
assert!(config
.profiles
.iter()
.any(|profile| profile.kind == ConnectionKind::LocalShell));
}
#[test]
fn duplicate_profile_ids_fail_validation() {
let mut config = AppConfig::default_linux();
config.profiles.push(
Profile::new("local", "Duplicate", ConnectionKind::LocalShell, "/bin/sh").unwrap(),
);
let err = config.validate().unwrap_err();
assert!(err.contains("duplicate profile"));
}
#[test]
fn empty_theme_id_fails_validation() {
let mut config = AppConfig::default_linux();
config.theme_id = " ".to_string();
let err = config.validate().unwrap_err();
assert!(err.contains("theme"));
}
}