gromnie_cli/wizards/
config.rs1use ratatui::Frame;
2use std::error::Error;
3
4use gromnie_client::config::GromnieConfig;
5
6use crate::app::App;
7use crate::draw::Draw;
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum ConfigWizardStage {
11 Welcome,
12 EnteringServerName,
13 EnteringServerHost,
14 EnteringServerPort,
15 EnteringAccountUsername,
16 EnteringAccountPassword,
17 EnteringCharacterName,
18 Confirming,
19 Complete,
20}
21
22#[derive(Clone)]
23pub struct ConfigWizard {
24 pub stage: ConfigWizardStage,
25 pub server_name: String,
26 pub server_host: String,
27 pub server_port: String,
28 pub account_username: String,
29 pub account_password: String,
30 pub character_name: String,
31 pub current_input: String,
32}
33
34impl Default for ConfigWizard {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl ConfigWizard {
41 pub fn new() -> Self {
42 Self {
43 stage: ConfigWizardStage::Welcome,
44 server_name: String::new(),
45 server_host: String::new(),
46 server_port: String::new(),
47 account_username: String::new(),
48 account_password: String::new(),
49 character_name: String::new(),
50 current_input: String::new(),
51 }
52 }
53
54 pub fn to_config(&self) -> GromnieConfig {
55 use std::collections::BTreeMap;
56
57 let mut servers = BTreeMap::new();
58 servers.insert(
59 self.server_name.clone(),
60 gromnie_client::config::ServerConfig {
61 host: self.server_host.clone(),
62 port: self.server_port.parse().unwrap_or(9000),
63 },
64 );
65
66 let mut accounts = BTreeMap::new();
67 accounts.insert(
70 self.account_username.clone(),
71 gromnie_client::config::AccountConfig {
72 username: self.account_username.clone(),
73 password: self.account_password.clone(),
74 character: None,
75 },
76 );
77
78 GromnieConfig {
79 servers,
80 accounts,
81 scripting: Default::default(),
82 reconnect: false,
83 }
84 }
85}
86
87impl Draw for ConfigWizard {
88 fn draw(self, _app: &mut App, frame: &mut Frame) -> Result<(), Box<dyn Error>> {
89 use ratatui::text::{Line, Text};
90 use ratatui::widgets::Paragraph;
91
92 let mut lines = Vec::new();
93
94 lines.push(Line::from("Welcome to Gromnie!"));
96 lines.push(Line::from(""));
97
98 match self.stage {
99 ConfigWizardStage::Welcome => {
100 lines.push(Line::from("No configuration file was found so the following prompts will help you create one."));
101 lines.push(Line::from(""));
102 }
103 _ => {
104 lines.push(Line::from("No configuration file was found so the following prompts will help you create one."));
105 lines.push(Line::from(""));
106
107 if self.stage != ConfigWizardStage::EnteringServerName {
109 lines.push(Line::from(" Server Name"));
110 lines.push(Line::from(format!(" {}", self.server_name)));
111 lines.push(Line::from(""));
112 }
113
114 if self.stage == ConfigWizardStage::EnteringServerName {
116 lines.push(Line::from(format!(
117 " Enter a server name: {}█",
118 self.current_input
119 )));
120 lines.push(Line::from(""));
121 }
122
123 if matches!(
125 self.stage,
126 ConfigWizardStage::EnteringServerPort
127 | ConfigWizardStage::EnteringAccountUsername
128 | ConfigWizardStage::EnteringAccountPassword
129 | ConfigWizardStage::Confirming
130 | ConfigWizardStage::Complete
131 ) {
132 lines.push(Line::from(" Hostname"));
133 lines.push(Line::from(format!(" {}", self.server_host)));
134 lines.push(Line::from(""));
135 }
136
137 if self.stage == ConfigWizardStage::EnteringServerHost {
139 lines.push(Line::from(format!(
140 " Enter a hostname: {}█",
141 self.current_input
142 )));
143 lines.push(Line::from(""));
144 }
145
146 if matches!(
148 self.stage,
149 ConfigWizardStage::EnteringAccountUsername
150 | ConfigWizardStage::EnteringAccountPassword
151 | ConfigWizardStage::Confirming
152 | ConfigWizardStage::Complete
153 ) {
154 lines.push(Line::from(" Port"));
155 lines.push(Line::from(format!(" {}", self.server_port)));
156 lines.push(Line::from(""));
157 }
158
159 if self.stage == ConfigWizardStage::EnteringServerPort {
161 lines.push(Line::from(format!(
162 " Enter a port (default: 9000): {}█",
163 self.current_input
164 )));
165 lines.push(Line::from(""));
166 }
167
168 if matches!(
170 self.stage,
171 ConfigWizardStage::EnteringAccountPassword
172 | ConfigWizardStage::Confirming
173 | ConfigWizardStage::Complete
174 ) {
175 lines.push(Line::from(" Account"));
176 lines.push(Line::from(format!(" {}", self.account_username)));
177 lines.push(Line::from(""));
178 }
179
180 if self.stage == ConfigWizardStage::EnteringAccountUsername {
182 lines.push(Line::from(format!(
183 " Enter account name: {}█",
184 self.current_input
185 )));
186 lines.push(Line::from(""));
187 }
188
189 if matches!(
191 self.stage,
192 ConfigWizardStage::EnteringCharacterName
193 | ConfigWizardStage::Confirming
194 | ConfigWizardStage::Complete
195 ) {
196 lines.push(Line::from(" Password"));
197 lines.push(Line::from(format!(
198 " {}",
199 "*".repeat(self.account_password.len())
200 )));
201 lines.push(Line::from(""));
202 }
203
204 if self.stage == ConfigWizardStage::EnteringAccountPassword {
206 lines.push(Line::from(format!(
207 " Enter a password: {}█",
208 "*".repeat(self.current_input.len())
209 )));
210 lines.push(Line::from(""));
211 }
212
213 if matches!(
215 self.stage,
216 ConfigWizardStage::Confirming | ConfigWizardStage::Complete
217 ) {
218 let char_display = if self.character_name.is_empty() {
219 "(not specified)".to_string()
220 } else {
221 self.character_name.clone()
222 };
223 lines.push(Line::from(" Character"));
224 lines.push(Line::from(format!(" {}", char_display)));
225 lines.push(Line::from(""));
226 }
227
228 if self.stage == ConfigWizardStage::EnteringCharacterName {
230 lines.push(Line::from(format!(
231 " Enter character name (* for any, leave empty to skip): {}█",
232 self.current_input
233 )));
234 lines.push(Line::from(""));
235 }
236
237 if self.stage == ConfigWizardStage::Confirming {
239 lines.push(Line::from(
240 "? Configuration complete. Press <enter> to save",
241 ));
242 }
243 }
244 }
245
246 let text = Text::from(lines);
247 let paragraph = Paragraph::new(text);
248 frame.render_widget(paragraph, frame.area());
249
250 Ok(())
251 }
252}