lean_ctx/core/config/
value_display.rs1use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
17#[serde(rename_all = "lowercase")]
18pub enum ValueDisplayMode {
19 Off,
20 #[default]
21 Minimal,
22 Milestones,
23 Verbose,
24}
25
26impl ValueDisplayMode {
27 pub fn parse(value: &str) -> Option<Self> {
28 match value.trim().to_ascii_lowercase().as_str() {
29 "off" | "0" | "false" | "none" => Some(Self::Off),
30 "minimal" | "on" | "1" | "true" => Some(Self::Minimal),
31 "milestones" => Some(Self::Milestones),
32 "verbose" => Some(Self::Verbose),
33 _ => None,
34 }
35 }
36}
37
38#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
43#[serde(rename_all = "lowercase")]
44pub enum StatuslineStyle {
45 #[default]
46 Brand,
47 Subtle,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
51#[serde(default)]
52pub struct ValueDisplayConfig {
53 pub mode: ValueDisplayMode,
55 pub statusline: StatuslineStyle,
57 pub recap_every_turns: u32,
59 pub recap_min_tokens: u64,
62 pub notifications: bool,
65 pub git_trailer: bool,
67}
68
69impl Default for ValueDisplayConfig {
70 fn default() -> Self {
71 Self {
72 mode: ValueDisplayMode::default(),
73 statusline: StatuslineStyle::default(),
74 recap_every_turns: 5,
78 recap_min_tokens: 10_000,
79 notifications: true,
80 git_trailer: false,
81 }
82 }
83}
84
85impl ValueDisplayConfig {
86 pub fn effective_mode(&self) -> ValueDisplayMode {
88 std::env::var("LEAN_CTX_VALUE_DISPLAY")
89 .ok()
90 .and_then(|v| ValueDisplayMode::parse(&v))
91 .unwrap_or(self.mode)
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn defaults_are_subtle_and_on() {
101 let cfg: ValueDisplayConfig = toml::from_str("").unwrap();
102 assert_eq!(cfg, ValueDisplayConfig::default());
103 assert_eq!(cfg.mode, ValueDisplayMode::Minimal);
104 assert!(!cfg.git_trailer);
105 }
106
107 #[test]
108 fn parses_toml_section() {
109 let cfg: ValueDisplayConfig =
110 toml::from_str("mode = \"off\"\nrecap_every_turns = 20").unwrap();
111 assert_eq!(cfg.mode, ValueDisplayMode::Off);
112 assert_eq!(cfg.recap_every_turns, 20);
113 assert_eq!(cfg.recap_min_tokens, 10_000);
114 assert_eq!(cfg.statusline, StatuslineStyle::Brand);
115 }
116
117 #[test]
118 fn statusline_style_parses() {
119 let cfg: ValueDisplayConfig = toml::from_str("statusline = \"subtle\"").unwrap();
120 assert_eq!(cfg.statusline, StatuslineStyle::Subtle);
121 assert!(toml::from_str::<ValueDisplayConfig>("statusline = \"loud\"").is_err());
122 }
123
124 #[test]
125 fn env_values_parse() {
126 assert_eq!(ValueDisplayMode::parse("OFF"), Some(ValueDisplayMode::Off));
127 assert_eq!(ValueDisplayMode::parse("0"), Some(ValueDisplayMode::Off));
128 assert_eq!(
129 ValueDisplayMode::parse("verbose"),
130 Some(ValueDisplayMode::Verbose)
131 );
132 assert_eq!(ValueDisplayMode::parse("loud"), None);
133 }
134}