Skip to main content

vtcode_config/
terminal_title.rs

1use serde::{Deserialize, Serialize};
2
3pub const DEFAULT_TERMINAL_TITLE_ITEMS: &[&str] = &["spinner", "project"];
4
5#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
6#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, Eq)]
7pub struct TerminalTitleConfig {
8    #[serde(default)]
9    pub items: Option<Vec<String>>,
10}
11
12impl TerminalTitleConfig {
13    #[must_use]
14    fn effective_items(&self) -> Vec<String> {
15        self.items
16            .clone()
17            .unwrap_or_else(|| DEFAULT_TERMINAL_TITLE_ITEMS.iter().map(|item| (*item).to_string()).collect())
18    }
19
20    #[must_use]
21    fn manages_title(&self) -> bool {
22        self.items.as_ref().is_none_or(|items| !items.is_empty())
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use super::{DEFAULT_TERMINAL_TITLE_ITEMS, TerminalTitleConfig};
29
30    #[test]
31    fn serde_defaults_when_terminal_title_table_is_missing() {
32        let config: TerminalTitleConfig = toml::from_str("").expect("config should parse");
33
34        assert_eq!(config.items, None);
35    }
36
37    #[test]
38    fn serde_preserves_explicit_empty_items() {
39        let config: TerminalTitleConfig = toml::from_str("items = []").expect("config should parse");
40
41        assert_eq!(config.items, Some(Vec::new()));
42    }
43
44    #[test]
45    fn serde_preserves_valid_item_list() {
46        let config: TerminalTitleConfig =
47            toml::from_str("items = [\"spinner\", \"project\", \"model\"]").expect("config should parse");
48
49        assert_eq!(config.items, Some(vec!["spinner".to_string(), "project".to_string(), "model".to_string()]));
50    }
51
52    #[test]
53    fn missing_items_uses_default_terminal_title_items() {
54        let config = TerminalTitleConfig::default();
55
56        assert_eq!(
57            config.effective_items(),
58            DEFAULT_TERMINAL_TITLE_ITEMS
59                .iter()
60                .map(|item| (*item).to_string())
61                .collect::<Vec<_>>()
62        );
63        assert!(config.manages_title());
64    }
65
66    #[test]
67    fn explicit_empty_items_disables_terminal_title_management() {
68        let config = TerminalTitleConfig { items: Some(Vec::new()) };
69
70        assert!(config.effective_items().is_empty());
71        assert!(!config.manages_title());
72    }
73
74    #[test]
75    fn explicit_items_are_preserved() {
76        let config = TerminalTitleConfig {
77            items: Some(vec!["project".to_string(), "model".to_string()]),
78        };
79
80        assert_eq!(config.effective_items(), vec!["project".to_string(), "model".to_string()]);
81        assert!(config.manages_title());
82    }
83}