diff --git a/bin/chat-cli/src/app.rs b/bin/chat-cli/src/app.rs index 6285c34..7233560 100644 --- a/bin/chat-cli/src/app.rs +++ b/bin/chat-cli/src/app.rs @@ -109,12 +109,11 @@ impl ChatApp { /// Load state from file. fn load_state(path: &PathBuf) -> AppState { - if path.exists() { - if let Ok(contents) = fs::read_to_string(path) { - if let Ok(state) = serde_json::from_str(&contents) { - return state; - } - } + if path.exists() + && let Ok(contents) = fs::read_to_string(path) + && let Ok(state) = serde_json::from_str(&contents) + { + return state; } AppState::default() } @@ -307,14 +306,14 @@ impl ChatApp { } let message = String::from_utf8_lossy(&content.data).to_string(); - if !message.is_empty() { - if let Some(session) = self.state.sessions.get_mut(from_user) { - session.messages.push(DisplayMessage { - from_self: false, - content: message, - timestamp: envelope.timestamp, - }); - } + if !message.is_empty() + && let Some(session) = self.state.sessions.get_mut(from_user) + { + session.messages.push(DisplayMessage { + from_self: false, + content: message, + timestamp: envelope.timestamp, + }); } self.save_state()?; @@ -334,11 +333,11 @@ impl ChatApp { timestamp: now(), }; - if let Some(active) = &self.state.active_chat.clone() { - if let Some(session) = self.state.sessions.get_mut(active) { - session.messages.push(msg); - return; - } + if let Some(active) = &self.state.active_chat.clone() + && let Some(session) = self.state.sessions.get_mut(active) + { + session.messages.push(msg); + return; } // No active chat - add to global messages self.global_messages.push(msg); @@ -443,11 +442,11 @@ impl ChatApp { Ok(Some(status)) } "/clear" => { - if let Some(active) = &self.state.active_chat { - if let Some(session) = self.state.sessions.get_mut(active) { - session.messages.clear(); - self.save_state()?; - } + if let Some(active) = &self.state.active_chat.clone() + && let Some(session) = self.state.sessions.get_mut(active) + { + session.messages.clear(); + self.save_state()?; } Ok(Some("Messages cleared".to_string())) } diff --git a/bin/chat-cli/src/transport.rs b/bin/chat-cli/src/transport.rs index 09c102b..022ea87 100644 --- a/bin/chat-cli/src/transport.rs +++ b/bin/chat-cli/src/transport.rs @@ -4,7 +4,7 @@ use std::collections::HashSet; use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; @@ -31,13 +31,12 @@ pub struct FileTransport { impl FileTransport { /// Create a new file transport. - pub fn new(user_name: &str, data_dir: &PathBuf) -> Result { + pub fn new(user_name: &str, data_dir: &Path) -> Result { let base_dir = data_dir.join("transport"); let inbox_dir = base_dir.join(user_name); - + // Create our inbox directory - fs::create_dir_all(&inbox_dir) - .context("Failed to create inbox directory")?; + fs::create_dir_all(&inbox_dir).context("Failed to create inbox directory")?; Ok(Self { user_name: user_name.to_string(), @@ -50,10 +49,9 @@ impl FileTransport { /// Send a message to a specific user. pub fn send(&self, to_user: &str, data: Vec) -> Result<()> { let target_dir = self.base_dir.join(to_user); - + // Create target inbox if it doesn't exist - fs::create_dir_all(&target_dir) - .context("Failed to create target inbox")?; + fs::create_dir_all(&target_dir).context("Failed to create target inbox")?; let envelope = MessageEnvelope { from: self.user_name.clone(), @@ -64,10 +62,9 @@ impl FileTransport { // Write message to a unique file let filename = format!("{}_{}.json", self.user_name, now()); let filepath = target_dir.join(&filename); - + let json = serde_json::to_string_pretty(&envelope)?; - fs::write(&filepath, json) - .context("Failed to write message file")?; + fs::write(&filepath, json).context("Failed to write message file")?; Ok(()) } @@ -82,13 +79,14 @@ impl FileTransport { for entry in entries.flatten() { let path = entry.path(); - + // Skip non-json files if path.extension().map(|e| e != "json").unwrap_or(true) { continue; } - let filename = path.file_name() + let filename = path + .file_name() .and_then(|n| n.to_str()) .unwrap_or("") .to_string(); @@ -99,13 +97,13 @@ impl FileTransport { } // Try to read and parse the message - if let Ok(contents) = fs::read_to_string(&path) { - if let Ok(envelope) = serde_json::from_str::(&contents) { - // Mark as processed and delete - self.processed.insert(filename); - let _ = fs::remove_file(&path); - return Some(envelope); - } + if let Ok(contents) = fs::read_to_string(&path) + && let Ok(envelope) = serde_json::from_str::(&contents) + { + // Mark as processed and delete + self.processed.insert(filename); + let _ = fs::remove_file(&path); + return Some(envelope); } } @@ -115,19 +113,18 @@ impl FileTransport { /// List available peers (users with inbox directories). pub fn list_peers(&self) -> Vec { let mut peers = Vec::new(); - + if let Ok(entries) = fs::read_dir(&self.base_dir) { for entry in entries.flatten() { - if entry.path().is_dir() { - if let Some(name) = entry.file_name().to_str() { - if name != self.user_name { - peers.push(name.to_string()); - } - } + if entry.path().is_dir() + && let Some(name) = entry.file_name().to_str() + && name != self.user_name + { + peers.push(name.to_string()); } } } - + peers } diff --git a/bin/chat-cli/src/ui.rs b/bin/chat-cli/src/ui.rs index 83e9dd3..42c5435 100644 --- a/bin/chat-cli/src/ui.rs +++ b/bin/chat-cli/src/ui.rs @@ -98,9 +98,10 @@ fn draw_messages(frame: &mut Frame, app: &ChatApp, area: Rect) { // Split content into lines that fit within inner_width. let content = &msg.content; if content.is_empty() { - return vec![ListItem::new(Line::from(vec![ - Span::styled(prefix_str, style.add_modifier(Modifier::BOLD)), - ]))]; + return vec![ListItem::new(Line::from(vec![Span::styled( + prefix_str, + style.add_modifier(Modifier::BOLD), + )]))]; } let mut items = Vec::new(); @@ -191,52 +192,52 @@ fn draw_status(frame: &mut Frame, app: &ChatApp, area: Rect) { /// Handle keyboard events. pub fn handle_events(app: &mut ChatApp) -> io::Result { // Poll for events with a short timeout to allow checking incoming messages - if event::poll(std::time::Duration::from_millis(100))? { - if let Event::Key(key) = event::read()? { - if key.kind != KeyEventKind::Press { - return Ok(true); + if event::poll(std::time::Duration::from_millis(100))? + && let Event::Key(key) = event::read()? + { + if key.kind != KeyEventKind::Press { + return Ok(true); + } + + match key.code { + KeyCode::Esc => return Ok(false), + // Handle Ctrl+C + KeyCode::Char('c') if key.modifiers.contains(event::KeyModifiers::CONTROL) => { + return Ok(false); } + KeyCode::Enter => { + if !app.input.is_empty() { + let input = std::mem::take(&mut app.input); - match key.code { - KeyCode::Esc => return Ok(false), - // Handle Ctrl+C - KeyCode::Char('c') if key.modifiers.contains(event::KeyModifiers::CONTROL) => { - return Ok(false); - } - KeyCode::Enter => { - if !app.input.is_empty() { - let input = std::mem::take(&mut app.input); - - if input.starts_with('/') { - match app.handle_command(&input) { - Ok(Some(response)) => { - app.status = response; - } - Ok(None) => { - // Quit signal - return Ok(false); - } - Err(e) => { - app.status = format!("Error: {}", e); - } + if input.starts_with('/') { + match app.handle_command(&input) { + Ok(Some(response)) => { + app.status = response; } - } else if app.current_session().is_some() { - if let Err(e) = app.send_message(&input) { - app.status = format!("Send error: {}", e); + Ok(None) => { + // Quit signal + return Ok(false); + } + Err(e) => { + app.status = format!("Error: {}", e); } - } else { - app.status = "No active chat. Use /connect first.".to_string(); } + } else if app.current_session().is_some() { + if let Err(e) = app.send_message(&input) { + app.status = format!("Send error: {}", e); + } + } else { + app.status = "No active chat. Use /connect first.".to_string(); } } - KeyCode::Char(c) => { - app.input.push(c); - } - KeyCode::Backspace => { - app.input.pop(); - } - _ => {} } + KeyCode::Char(c) => { + app.input.push(c); + } + KeyCode::Backspace => { + app.input.pop(); + } + _ => {} } }