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    pub fn effective_items(&self) -> Vec<String> {
15        self.items.clone().unwrap_or_else(|| {
16            DEFAULT_TERMINAL_TITLE_ITEMS
17                .iter()
18                .map(|item| (*item).to_string())
19                .collect()
20        })
21    }
22
23    #[must_use]
24    pub fn manages_title(&self) -> bool {
25        self.items.as_ref().is_none_or(|items| !items.is_empty())
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use super::{DEFAULT_TERMINAL_TITLE_ITEMS, TerminalTitleConfig};
32
33    #[test]
34    fn serde_defaults_when_terminal_title_table_is_missing() {
35        let config: TerminalTitleConfig = toml::from_str("").expect("config should parse");
36
37        assert_eq!(config.items, None);
38    }
39
40    #[test]
41    fn serde_preserves_explicit_empty_items() {
42        let config: TerminalTitleConfig =
43            toml::from_str("items = []").expect("config should parse");
44
45        assert_eq!(config.items, Some(Vec::new()));
46    }
47
48    #[test]
49    fn serde_preserves_valid_item_list() {
50        let config: TerminalTitleConfig =
51            toml::from_str("items = [\"spinner\", \"project\", \"model\"]")
52                .expect("config should parse");
53
54        assert_eq!(
55            config.items,
56            Some(vec![
57                "spinner".to_string(),
58                "project".to_string(),
59                "model".to_string()
60            ])
61        );
62    }
63
64    #[test]
65    fn missing_items_uses_default_terminal_title_items() {
66        let config = TerminalTitleConfig::default();
67
68        assert_eq!(
69            config.effective_items(),
70            DEFAULT_TERMINAL_TITLE_ITEMS
71                .iter()
72                .map(|item| (*item).to_string())
73                .collect::<Vec<_>>()
74        );
75        assert!(config.manages_title());
76    }
77
78    #[test]
79    fn explicit_empty_items_disables_terminal_title_management() {
80        let config = TerminalTitleConfig {
81            items: Some(Vec::new()),
82        };
83
84        assert!(config.effective_items().is_empty());
85        assert!(!config.manages_title());
86    }
87
88    #[test]
89    fn explicit_items_are_preserved() {
90        let config = TerminalTitleConfig {
91            items: Some(vec!["project".to_string(), "model".to_string()]),
92        };
93
94        assert_eq!(
95            config.effective_items(),
96            vec!["project".to_string(), "model".to_string()]
97        );
98        assert!(config.manages_title());
99    }
100}