This commit is contained in:
@@ -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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,11 @@
|
|||||||
//! This crate is intentionally dependency-light so terminal/profile/session behavior can be
|
//! This crate is intentionally dependency-light so terminal/profile/session behavior can be
|
||||||
//! unit-tested without starting the desktop shell.
|
//! unit-tested without starting the desktop shell.
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
pub mod feature;
|
pub mod feature;
|
||||||
pub mod workspace;
|
pub mod workspace;
|
||||||
|
|
||||||
|
pub use config::{AppConfig, ShortcutBinding};
|
||||||
pub use feature::{
|
pub use feature::{
|
||||||
all_features, feature_by_key, feature_matrix, FeatureArea, FeatureSpec, FeatureStatus,
|
all_features, feature_by_key, feature_matrix, FeatureArea, FeatureSpec, FeatureStatus,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user