1+ use anyhow:: Result ;
12use serde:: { Deserialize , Serialize } ;
23use std:: path:: { Path , PathBuf } ;
34
4- use crate :: { ui:: Theme , utils} ;
5+ use crate :: {
6+ ui:: Theme ,
7+ utils:: { absolute_path_as_string, data_dir, format_path_for_display, user_home_dir} ,
8+ } ;
59
610pub const CONFIG_NAME : & str = "config.toml" ;
711
8- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
12+ #[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
913pub struct AppConfig {
10- /// Define the app theme [Light, Dark, Dracula, Indigo]
11- theme : Theme ,
14+ /// The default app theme on start up [Light, Dark, Dracula, Indigo]
15+ default_theme : Theme ,
1216 /// Directory in which the Explorer should start
1317 start_dir : PathBuf ,
1418 /// Directory to which the search results are to be exported
1519 export_dir : PathBuf ,
1620 /// Enable/Disable following symbolic links
1721 follow_sym_links : bool ,
22+ /// Update Rate per second for the System-Overview
23+ system_update_rate : u8 ,
24+ /// Frames per Second (Rendering)
25+ fps : u8 ,
1826}
1927
2028impl Default for AppConfig {
2129 fn default ( ) -> Self {
2230 Self {
23- theme : Default :: default ( ) ,
24- start_dir : utils :: user_home_dir ( ) . map_or (
31+ default_theme : Default :: default ( ) ,
32+ start_dir : user_home_dir ( ) . map_or (
2533 {
2634 std:: env:: current_dir ( )
2735 . ok ( )
2836 . unwrap_or ( PathBuf :: new ( ) . join ( "." ) )
2937 } ,
3038 |home_dir| home_dir,
3139 ) ,
32- export_dir : utils :: data_dir ( ) ,
40+ export_dir : data_dir ( ) ,
3341 follow_sym_links : false ,
42+ system_update_rate : 1 ,
43+ fps : 45 ,
3444 }
3545 }
3646}
3747
3848impl AppConfig {
39- fn ignore_given_init_dir ( & mut self ) {
40- self . start_dir = utils:: user_home_dir ( ) . map_or (
41- {
42- std:: env:: current_dir ( )
43- . ok ( )
44- . unwrap_or ( PathBuf :: new ( ) . join ( "." ) )
45- } ,
46- |home_dir| home_dir,
47- ) ;
48- }
49-
50- fn ignore_given_export_dir ( & mut self ) {
51- self . export_dir = utils:: data_dir ( ) ;
52- }
53-
5449 pub fn load_config < P : AsRef < Path > > ( p : P ) -> AppConfig {
5550 let config_file = p. as_ref ( ) ;
5651
5752 if !config_file. exists ( ) {
5853 let config = AppConfig :: default ( ) ;
5954 // If no config found, try to store a new config file at start up
60- if let Err ( config_err ) = confy:: store_path ( config_file, config. clone ( ) ) {
55+ if let Err ( err ) = confy:: store_path ( config_file, config. clone ( ) ) {
6156 log:: error!(
62- "Failed to store a new configuration file at '{}' " ,
63- utils :: absolute_path_as_string( config_file)
57+ "Failed to store a new configuration file at [{}] " ,
58+ absolute_path_as_string( config_file)
6459 ) ;
65- log:: error!( "Config error: {:#?}" , config_err) ;
66- log:: error!( "Fallback to the default configuration" ) ;
60+ AppConfig :: log_confy_err ( err) ;
6761 }
6862 config
6963 } else {
7064 // Try to load the given configuration file
7165 match confy:: load_path :: < AppConfig > ( config_file) {
7266 Ok ( config) => config. validate_config ( ) ,
73- Err ( config_err ) => {
67+ Err ( err ) => {
7468 log:: error!(
75- "Failed to load configuration file '{}' " ,
76- utils :: absolute_path_as_string( config_file)
69+ "Failed to load configuration file [{}] " ,
70+ absolute_path_as_string( config_file)
7771 ) ;
78- log:: error!( "Config error: {:#?}" , config_err) ;
79- log:: error!( "Fallback to the default configuration" ) ;
72+ AppConfig :: log_confy_err ( err) ;
8073 AppConfig :: default ( )
8174 }
8275 }
8376 }
8477 }
8578
79+ fn log_confy_err < T : std:: error:: Error > ( err : T ) {
80+ log:: error!( "{:#?}" , err) ;
81+ log:: warn!( "Fallback to the default configuration" ) ;
82+ }
83+
84+ pub fn save_config < P : AsRef < Path > > ( & self , p : P ) -> Result < ( ) > {
85+ confy:: store_path ( p. as_ref ( ) , self ) ?;
86+ Ok ( ( ) )
87+ }
88+
8689 fn validate_config ( self ) -> Self {
8790 let mut config = self . clone ( ) ;
8891
89- if !self . start_dir . is_dir ( ) {
90- log:: error!( "Invalid path found for config option 'start_dir' -> path will be ignored, fallback to default" ) ;
91- config. ignore_given_init_dir ( ) ;
92+ if !config. start_dir . is_dir ( ) {
93+ let start_dir = user_home_dir ( ) . map_or (
94+ {
95+ std:: env:: current_dir ( )
96+ . ok ( )
97+ . unwrap_or ( PathBuf :: new ( ) . join ( "." ) )
98+ } ,
99+ |home_dir| home_dir,
100+ ) ;
101+ log:: warn!(
102+ "[Config] Invalid path for option 'start_dir' -> No such directory, fallback to default [{}]" ,
103+ absolute_path_as_string( & start_dir)
104+ ) ;
105+
106+ config. start_dir = start_dir;
107+ }
108+
109+ if !config. export_dir . is_dir ( ) {
110+ let export_dir = data_dir ( ) ;
111+ log:: warn!(
112+ "[Config] Invalid path for option 'export_dir' -> No such directory, fallback to default [{}]" ,
113+ absolute_path_as_string( & export_dir)
114+ ) ;
115+ config. export_dir = export_dir;
116+ }
117+
118+ if config. fps > 60 {
119+ let default_fps: u8 = 45 ;
120+ log:: warn!(
121+ "[Config] Invalid value for option 'fps' -> It cannot be greater than 60, fallback to default [{}]" ,
122+ default_fps
123+ ) ;
124+ config. fps = default_fps;
92125 }
93126
94- if !self . export_dir . is_dir ( ) {
95- log:: error!(
96- "Invalid path found for config option 'export_dir' -> path will be ignored, fallback to default"
127+ if config. system_update_rate > 5 {
128+ let default_update_rate: u8 = 1 ;
129+ log:: warn!(
130+ "[Config] Invalid value for option 'system_update_rate' -> It cannot be greater than 5, fallback to default [{}]" ,
131+ default_update_rate
97132 ) ;
98- config. ignore_given_export_dir ( ) ;
133+ config. system_update_rate = default_update_rate ;
99134 }
100135
101136 config
102137 }
103138
139+ pub fn config_docs ( & self , with_description : bool ) -> Vec < Vec < String > > {
140+ let start_dir = format_path_for_display ( absolute_path_as_string ( self . start_dir ( ) ) ) ;
141+ let export_dir = format_path_for_display ( absolute_path_as_string ( self . export_dir ( ) ) ) ;
142+ let follow_sym_links = if self . follow_sym_links ( ) { "Yes" } else { "No" } ;
143+ let fps = format ! ( "{} / sec" , self . fps( ) ) ;
144+ let update_rate = format ! ( "{} / sec" , self . system_update_rate( ) ) ;
145+
146+ let rows = vec ! [
147+ (
148+ "Default theme" ,
149+ self . theme( ) . to_string( ) ,
150+ "App theme at startup" ,
151+ ) ,
152+ (
153+ "Start directory" ,
154+ start_dir,
155+ "Explorer directory at startup" ,
156+ ) ,
157+ (
158+ "Export directory" ,
159+ export_dir,
160+ "Directory to which the search results are exported" ,
161+ ) ,
162+ (
163+ "Follow symbolic links" ,
164+ follow_sym_links. to_string( ) ,
165+ "Defines whether Explorer follows symbolic links" ,
166+ ) ,
167+ (
168+ "Frames per second (render)" ,
169+ fps,
170+ "Frames per second (TUI render)" ,
171+ ) ,
172+ (
173+ "Update rate (System-Resources)" ,
174+ update_rate,
175+ "Update rate of system resource usage per second" ,
176+ ) ,
177+ ] ;
178+
179+ rows. into_iter ( )
180+ . map ( |( key, value, desc) | {
181+ if with_description {
182+ vec ! [ key. into( ) , value, desc. into( ) ]
183+ } else {
184+ vec ! [ key. into( ) , value]
185+ }
186+ } )
187+ . collect ( )
188+ }
189+
190+ pub fn set_theme ( & mut self , t : Theme ) {
191+ self . default_theme = t;
192+ }
193+
194+ pub fn set_start_dir < P : AsRef < Path > > ( & mut self , p : P ) {
195+ self . start_dir = p. as_ref ( ) . to_path_buf ( ) ;
196+ }
197+
198+ pub fn set_export_dir < P : AsRef < Path > > ( & mut self , p : P ) {
199+ self . export_dir = p. as_ref ( ) . to_path_buf ( ) ;
200+ }
201+
202+ pub fn set_follow_sym_links ( & mut self , yes : bool ) {
203+ self . follow_sym_links = yes;
204+ }
205+
206+ pub fn set_system_update_rate ( & mut self , rate : u8 ) {
207+ self . system_update_rate = rate;
208+ }
209+
210+ pub fn set_fps ( & mut self , fps : u8 ) {
211+ self . fps = fps;
212+ }
213+
104214 pub fn theme ( & self ) -> Theme {
105- self . theme
215+ self . default_theme
106216 }
107217
108218 pub fn start_dir ( & self ) -> PathBuf {
@@ -116,4 +226,12 @@ impl AppConfig {
116226 pub fn follow_sym_links ( & self ) -> bool {
117227 self . follow_sym_links
118228 }
229+
230+ pub fn system_update_rate ( & self ) -> u8 {
231+ self . system_update_rate
232+ }
233+
234+ pub fn fps ( & self ) -> u8 {
235+ self . fps
236+ }
119237}
0 commit comments