diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-01 16:26:21 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-01 16:26:21 +0100 |
| commit | a036e7eb46886ff7fe88255ae26c327f63ec4bfa (patch) | |
| tree | 494911ce0d394041c00eff276632e4f5f48f3fb5 /src/bin/client | |
| parent | v3.2.0: straight and split bets anywhere on the felt; add history command (diff) | |
| download | zagan-bet-a036e7eb46886ff7fe88255ae26c327f63ec4bfa.tar.gz zagan-bet-a036e7eb46886ff7fe88255ae26c327f63ec4bfa.zip | |
v3.3.0: keep client.db in the XDG data dir, add -d/--data-dir
Diffstat (limited to '')
| -rw-r--r-- | src/bin/client/main.rs | 35 | ||||
| -rw-r--r-- | src/bin/client/repl.rs | 12 |
2 files changed, 35 insertions, 12 deletions
diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index 9018026..3407380 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs | |||
| @@ -5,10 +5,21 @@ mod repl; | |||
| 5 | mod tls; | 5 | mod tls; |
| 6 | 6 | ||
| 7 | use repl::ClientState; | 7 | use repl::ClientState; |
| 8 | use zagan_bet::client::paths::{database_path, default_data_dir, parse_args, USAGE}; | ||
| 8 | 9 | ||
| 9 | fn main() { | 10 | fn main() { |
| 10 | let args: Vec<String> = std::env::args().collect(); | 11 | let args = match parse_args(std::env::args().skip(1)) { |
| 11 | let unsafe_mode = args.iter().any(|arg| arg == "--unsafe"); | 12 | Ok(args) => args, |
| 13 | Err(message) => { | ||
| 14 | eprintln!("{message}"); | ||
| 15 | std::process::exit(2); | ||
| 16 | } | ||
| 17 | }; | ||
| 18 | |||
| 19 | if args.help { | ||
| 20 | println!("{USAGE}"); | ||
| 21 | return; | ||
| 22 | } | ||
| 12 | 23 | ||
| 13 | // Every game board is drawn in place, so refuse a terminal that cannot fit | 24 | // Every game board is drawn in place, so refuse a terminal that cannot fit |
| 14 | // them before touching the network or the terminal mode. | 25 | // them before touching the network or the terminal mode. |
| @@ -25,19 +36,33 @@ fn main() { | |||
| 25 | std::process::exit(1); | 36 | std::process::exit(1); |
| 26 | } | 37 | } |
| 27 | 38 | ||
| 28 | if unsafe_mode { | 39 | if args.unsafe_mode { |
| 29 | println!("WARNING: Running in UNSAFE mode - certificate verification disabled!"); | 40 | println!("WARNING: Running in UNSAFE mode - certificate verification disabled!"); |
| 30 | } | 41 | } |
| 31 | 42 | ||
| 32 | connection::set_unsafe_mode(unsafe_mode); | 43 | connection::set_unsafe_mode(args.unsafe_mode); |
| 33 | 44 | ||
| 34 | let mut state = ClientState::new(); | 45 | let data_dir = args.data_dir.unwrap_or_else(default_data_dir); |
| 46 | if let Err(error) = std::fs::create_dir_all(&data_dir) { | ||
| 47 | eprintln!("Cannot create {}: {error}", data_dir.display()); | ||
| 48 | std::process::exit(1); | ||
| 49 | } | ||
| 50 | let db_path = database_path(&data_dir); | ||
| 51 | |||
| 52 | let mut state = match ClientState::new(&db_path) { | ||
| 53 | Ok(state) => state, | ||
| 54 | Err(error) => { | ||
| 55 | eprintln!("{error}"); | ||
| 56 | std::process::exit(1); | ||
| 57 | } | ||
| 58 | }; | ||
| 35 | if let Some(host) = state.addr.clone() { | 59 | if let Some(host) = state.addr.clone() { |
| 36 | state.connect_to(&host); | 60 | state.connect_to(&host); |
| 37 | } | 61 | } |
| 38 | 62 | ||
| 39 | println!("Welcome to Zagan-Bet Client!"); | 63 | println!("Welcome to Zagan-Bet Client!"); |
| 40 | println!("Type 'help' for available commands."); | 64 | println!("Type 'help' for available commands."); |
| 65 | println!("Data: {}", db_path.display()); | ||
| 41 | 66 | ||
| 42 | state.run(); | 67 | state.run(); |
| 43 | } | 68 | } |
diff --git a/src/bin/client/repl.rs b/src/bin/client/repl.rs index bf02c8d..1debff1 100644 --- a/src/bin/client/repl.rs +++ b/src/bin/client/repl.rs | |||
| @@ -43,11 +43,9 @@ pub struct ClientState { | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | impl ClientState { | 45 | impl ClientState { |
| 46 | pub fn new() -> Self { | 46 | pub fn new(db_path: &std::path::Path) -> Result<Self, String> { |
| 47 | let conn = rusqlite::Connection::open( | 47 | let conn = rusqlite::Connection::open(db_path) |
| 48 | std::env::var("CLIENT_DB").unwrap_or_else(|_| "client.db".to_string()), | 48 | .map_err(|error| format!("cannot open {}: {error}", db_path.display()))?; |
| 49 | ) | ||
| 50 | .unwrap(); | ||
| 51 | database::init_db(&conn); | 49 | database::init_db(&conn); |
| 52 | let default_ip = "127.0.0.1".to_string(); | 50 | let default_ip = "127.0.0.1".to_string(); |
| 53 | let default_port = 11525; | 51 | let default_port = 11525; |
| @@ -55,7 +53,7 @@ impl ClientState { | |||
| 55 | let default_host = format!("{}:{}", default_ip, default_port); | 53 | let default_host = format!("{}:{}", default_ip, default_port); |
| 56 | let addr = last_host.or(Some(default_host)); | 54 | let addr = last_host.or(Some(default_host)); |
| 57 | 55 | ||
| 58 | Self { | 56 | Ok(Self { |
| 59 | stream: None, | 57 | stream: None, |
| 60 | conn, | 58 | conn, |
| 61 | addr, | 59 | addr, |
| @@ -66,7 +64,7 @@ impl ClientState { | |||
| 66 | prompt_text: String::new(), | 64 | prompt_text: String::new(), |
| 67 | terminal_size: crossterm::terminal::size().unwrap_or((MIN_COLUMNS, MIN_ROWS)), | 65 | terminal_size: crossterm::terminal::size().unwrap_or((MIN_COLUMNS, MIN_ROWS)), |
| 68 | size_warned: None, | 66 | size_warned: None, |
| 69 | } | 67 | }) |
| 70 | } | 68 | } |
| 71 | 69 | ||
| 72 | pub fn connect_to(&mut self, addr: &str) { | 70 | pub fn connect_to(&mut self, addr: &str) { |
