toon_format/tui/state/
file_state.rs1use std::path::PathBuf;
4
5use chrono::{
6 DateTime,
7 Local,
8};
9
10#[derive(Debug, Clone)]
12pub struct FileEntry {
13 pub path: PathBuf,
14 pub is_dir: bool,
15 pub size: u64,
16 pub modified: Option<DateTime<Local>>,
17}
18
19impl FileEntry {
20 pub fn name(&self) -> String {
21 self.path
22 .file_name()
23 .and_then(|n| n.to_str())
24 .unwrap_or("")
25 .to_string()
26 }
27
28 pub fn is_json(&self) -> bool {
29 !self.is_dir && self.path.extension().and_then(|e| e.to_str()) == Some("json")
30 }
31
32 pub fn is_toon(&self) -> bool {
33 !self.is_dir && self.path.extension().and_then(|e| e.to_str()) == Some("toon")
34 }
35}
36
37#[derive(Debug, Clone)]
39pub struct ConversionHistory {
40 pub timestamp: DateTime<Local>,
41 pub mode: String,
42 pub input_file: Option<PathBuf>,
43 pub output_file: Option<PathBuf>,
44 pub token_savings: f64,
45 pub byte_savings: f64,
46}
47
48pub struct FileState {
50 pub current_file: Option<PathBuf>,
51 pub current_dir: PathBuf,
52 pub selected_files: Vec<PathBuf>,
53 pub history: Vec<ConversionHistory>,
54 pub is_modified: bool,
55}
56
57impl FileState {
58 pub fn new() -> Self {
59 Self {
60 current_file: None,
61 current_dir: std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
62 selected_files: Vec::new(),
63 history: Vec::new(),
64 is_modified: false,
65 }
66 }
67
68 pub fn set_current_file(&mut self, path: PathBuf) {
69 self.current_file = Some(path.clone());
70 self.current_dir = path
71 .parent()
72 .map(|p| p.to_path_buf())
73 .unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
74 self.is_modified = false;
75 }
76
77 pub fn clear_current_file(&mut self) {
78 self.current_file = None;
79 self.is_modified = false;
80 }
81
82 pub fn mark_modified(&mut self) {
83 self.is_modified = true;
84 }
85
86 pub fn add_to_history(&mut self, entry: ConversionHistory) {
87 self.history.push(entry);
88 if self.history.len() > 50 {
89 self.history.remove(0);
90 }
91 }
92
93 pub fn toggle_file_selection(&mut self, path: PathBuf) {
94 if let Some(pos) = self.selected_files.iter().position(|p| p == &path) {
95 self.selected_files.remove(pos);
96 } else {
97 self.selected_files.push(path);
98 }
99 }
100
101 pub fn clear_selection(&mut self) {
102 self.selected_files.clear();
103 }
104
105 pub fn is_selected(&self, path: &PathBuf) -> bool {
106 self.selected_files.contains(path)
107 }
108}
109
110impl Default for FileState {
111 fn default() -> Self {
112 Self::new()
113 }
114}