use std::io::{BufRead, BufReader, Write, stdin, stdout}; use std::net::TcpStream; use rusqlite::Connection; use crate::connection; use crate::database; pub struct ClientState { pub stream: Option, pub conn: Connection, pub addr: Option, pub default_port: u16, } impl ClientState { pub fn new() -> Self { let conn = database::init_db(); let default_ip = "127.0.0.1".to_string(); let default_port = 11525; let last_host = database::get_last_host(&conn); let default_host = format!("{}:{}", default_ip, default_port); let addr = last_host.or(Some(default_host)); Self { stream: None, conn, addr, default_port, } } pub fn connect_to(&mut self, addr: &str) { self.addr = Some(addr.to_string()); match connection::connect(addr) { Ok(s) => { self.stream = Some(s); database::save_host(&self.conn, addr); } Err(e) => println!("Failed to connect: {}", e), } } pub fn run(&mut self) { loop { print!("> "); stdout().flush().unwrap(); let mut line = String::new(); stdin().read_line(&mut line).unwrap(); let line = line.trim(); if line.is_empty() { continue; } let parts: Vec<&str> = line.splitn(2, ' ').collect(); match parts[0] { "connect" => { let addr_str = if parts.len() < 2 { if let Some(h) = &self.addr { h.clone() } else { println!("No host specified and no previous connection. Usage: connect :"); continue; } } else { let mut a = parts[1].to_string(); if !a.contains(':') { a = format!("{}:{}", a, self.default_port); } a }; self.connect_to(&addr_str); } "send" => { if self.stream.is_none() { println!("Not connected. Use 'connect :' first."); continue; } if parts.len() < 2 { println!("Usage: send "); continue; } let msg = parts[1]; let s = self.stream.as_mut().unwrap(); let writer_stream = s.try_clone().unwrap(); let mut writer = writer_stream; let response_reader_stream = s.try_clone().unwrap(); let mut response_reader = BufReader::new(response_reader_stream); writeln!(writer, "{}", msg).unwrap(); let mut response = String::new(); response_reader.read_line(&mut response).unwrap(); println!("Echo: {}", response.trim()); } "disconnect" => { self.stream = None; println!("Disconnected"); } "help" => { help(); } "quit" => break, _ => help(), } } } } fn help() { println!("Available commands: connect :, send , disconnect, help, quit"); }