Skip to main content

stynx_code_tui/
persistence.rs

1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5use crate::state::AppState;
6use crate::theme;
7
8#[derive(Debug, Clone, Default, Serialize, Deserialize)]
9pub struct TuiState {
10    #[serde(default)]
11    pub theme: Option<String>,
12    #[serde(default)]
13    pub sidebar_visible: Option<bool>,
14    #[serde(default)]
15    pub tool_details: Option<bool>,
16    #[serde(default)]
17    pub recent_models: Vec<String>,
18}
19
20fn state_path() -> Option<PathBuf> {
21    let home = std::env::var_os("HOME")?;
22    let path = PathBuf::from(home)
23        .join(".stynx-code")
24        .join("tui-state.json");
25    Some(path)
26}
27
28pub fn load() -> TuiState {
29    let Some(path) = state_path() else { return TuiState::default(); };
30    let Ok(data) = std::fs::read_to_string(&path) else { return TuiState::default(); };
31    serde_json::from_str(&data).unwrap_or_default()
32}
33
34pub fn save(state: &TuiState) {
35    let Some(path) = state_path() else { return; };
36    if let Some(parent) = path.parent() {
37        let _ = std::fs::create_dir_all(parent);
38    }
39    let Ok(data) = serde_json::to_string_pretty(state) else { return; };
40    let _ = std::fs::write(&path, data);
41}
42
43pub fn apply_to(state: &mut AppState, persisted: &TuiState) {
44    if let Some(id) = &persisted.theme {
45        theme::set_theme(id);
46    }
47    if let Some(v) = persisted.sidebar_visible {
48        state.sidebar.visible = v;
49    }
50    if let Some(v) = persisted.tool_details {
51        state.tool_details = v;
52    }
53    if !persisted.recent_models.is_empty() {
54        state.recent_models = persisted.recent_models.clone();
55    }
56}
57
58pub fn snapshot(state: &AppState) -> TuiState {
59    TuiState {
60        theme: Some(theme::current().id.to_string()),
61        sidebar_visible: Some(state.sidebar.visible),
62        tool_details: Some(state.tool_details),
63        recent_models: state.recent_models.clone(),
64    }
65}