1#![allow(non_snake_case)]
2use std::{fmt::Display, path::PathBuf};
3
4use crate::display::menuopts::CUTE_LOGO;
5
6use database::db::DB;
7use dirs::config_dir;
8use serde::{Deserialize, Serialize};
9use tui::style::Style;
10
11pub mod app;
13
14pub mod database;
16
17pub mod screens;
19
20pub mod display;
22
23pub mod request;
25
26pub mod events;
28
29pub mod tui_cute;
30
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct Config {
33 colors: Colors,
34 logo: Option<Logo>,
35 db_path: Option<PathBuf>,
36}
37
38impl Config {
39 pub fn get_fg_color(&self) -> tui::style::Color {
40 self.colors.get_fg()
41 }
42 pub fn set_db_path(&mut self, path: PathBuf) {
43 self.db_path = Some(path);
44 }
45 pub fn get_bg_color(&self) -> tui::style::Color {
46 self.colors.get_bg()
47 }
48 pub fn get_body_color(&self) -> tui::style::Color {
49 self.colors.body.get_value()
50 }
51 pub fn get_outline_color(&self) -> tui::style::Color {
52 self.colors.outline.get_value()
53 }
54 pub fn get_logo(&self) -> &str {
55 if self.logo == Some(Logo::Default) {
56 CUTE_LOGO
57 } else {
58 ""
59 }
60 }
61
62 pub fn get_style(&self) -> Style {
63 Style::default()
64 .fg(self.get_fg_color())
65 .bg(self.get_bg_color())
66 }
67
68 pub fn get_style_error(&self) -> Style {
69 Style::default()
70 .fg(tui::style::Color::Red)
71 .bg(self.get_bg_color())
72 }
73
74 pub fn get_default_config() -> Self {
75 Self {
76 colors: Colors {
77 fg: ConfigColor::Gray,
78 bg: ConfigColor::Black,
79 body: ConfigColor::Yellow,
80 outline: ConfigColor::Cyan,
81 },
82 logo: Some(Logo::Default),
83 db_path: Some(DB::get_default_path()),
84 }
85 }
86
87 pub fn load() -> Result<Self, String> {
88 if let Some(config) = config_dir() {
89 let config = config.join("CuTE").join("config.toml");
90 if let Ok(config) = std::fs::read_to_string(config) {
91 if let Ok(config) = toml::from_str::<Config>(&config) {
92 Ok(config)
93 } else {
94 Err("Failed to parse config.toml".to_string())
95 }
96 } else {
97 Err("Failed to read config.toml".to_string())
98 }
99 } else {
100 Err("Failed to get config directory".to_string())
101 }
102 }
103
104 pub fn get_db_path(&self) -> Option<PathBuf> {
105 self.db_path.as_ref().cloned()
106 }
107}
108impl Default for Config {
109 fn default() -> Self {
110 if let Ok(config) = Self::load() {
111 config
112 } else {
113 Self::get_default_config()
114 }
115 }
116}
117
118#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
119pub enum Logo {
120 #[default]
121 Default,
122 None,
123}
124
125impl Display for Logo {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 match self {
128 Logo::Default => write!(f, "{}", CUTE_LOGO),
129 Logo::None => write!(f, ""),
130 }
131 }
132}
133
134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
135pub struct Colors {
136 fg: ConfigColor,
137 bg: ConfigColor,
138 body: ConfigColor,
139 outline: ConfigColor,
140}
141
142#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
143enum ConfigColor {
144 Red,
145 Blue,
146 Cyan,
147 Magenta,
148 Gray,
149 Black,
150 White,
151 Green,
152 Yellow,
153}
154
155impl Colors {
156 pub fn get_fg(&self) -> tui::style::Color {
157 self.fg.get_value()
158 }
159 pub fn get_bg(&self) -> tui::style::Color {
160 self.bg.get_value()
161 }
162}
163
164impl ConfigColor {
165 pub fn get_value(&self) -> tui::style::Color {
166 match self {
167 ConfigColor::Red => tui::style::Color::Red,
168 ConfigColor::Blue => tui::style::Color::Blue,
169 ConfigColor::Cyan => tui::style::Color::Cyan,
170 ConfigColor::Magenta => tui::style::Color::Magenta,
171 ConfigColor::Gray => tui::style::Color::Gray,
172 ConfigColor::Black => tui::style::Color::Black,
173 ConfigColor::White => tui::style::Color::White,
174 ConfigColor::Green => tui::style::Color::Green,
175 ConfigColor::Yellow => tui::style::Color::Yellow,
176 }
177 }
178}