diff --git a/build.rs b/build.rs index c4d6b78..77d0437 100644 --- a/build.rs +++ b/build.rs @@ -36,8 +36,8 @@ fn main() -> Result<()> { continue; } - let key = PrivateKey::random(&mut rng, algo.to_owned()) - .map_err(anyhow::Error::from)?; + let key = + PrivateKey::random(&mut rng, algo.to_owned()).map_err(anyhow::Error::from)?; key.write_openssh_file(&path, LineEnding::default())?; } diff --git a/rust-toolchain b/rust-toolchain index fb465b8..eaac998 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,3 @@ [toolchain] -channel = "stable" -version = "1.87" +channel = "nightly-2025-03-28" components = ["clippy", "rust-analyzer", "cargo", "rustc"] diff --git a/src/action.rs b/src/action.rs index 06549a5..c73f2bc 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,6 +1,7 @@ use std::fmt; -use serde::{de::{self, Visitor}, Deserialize, Deserializer, Serialize}; +use serde::de::{self, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; use strum::Display; #[derive(Debug, Clone, PartialEq, Eq, Display, Serialize)] @@ -30,8 +31,8 @@ pub enum Action { impl<'de> Deserialize<'de> for Action { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> - { + where + D: Deserializer<'de>, { struct ActionVisitor; impl<'de> Visitor<'de> for ActionVisitor { @@ -42,8 +43,8 @@ impl<'de> Deserialize<'de> for Action { } fn visit_str(self, v: &str) -> Result - where E: de::Error - { + where + E: de::Error, { if v == "Continue" { Ok(Action::Continue(None)) } else { @@ -62,7 +63,7 @@ impl<'de> Deserialize<'de> for Action { SelectNext, SelectPrev, } - + let helper: Helper = serde_json::from_str(&format!("\"{}\"", v)) .map_err(|_| de::Error::unknown_variant(v, &["Continue"]))?; Ok(match helper { diff --git a/src/app.rs b/src/app.rs index 8ef1c8a..76fed9e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -416,8 +416,8 @@ impl App { // If blog feature is not enabled, render a placeholder content_rect.height = 1; let placeholder = Paragraph::new( - "Blog feature is disabled. Enable the `blog` feature \ - to view this tab.", + "Blog feature is disabled. Enable the `blog` feature to view this \ + tab.", ) .style(Style::default().fg(Color::Red).add_modifier(Modifier::BOLD)); diff --git a/src/atproto/mod.rs b/src/atproto/mod.rs index 457efc4..47f0429 100644 --- a/src/atproto/mod.rs +++ b/src/atproto/mod.rs @@ -28,30 +28,20 @@ pub mod blog { lazy_static! { static ref POSTS_CACHE_STORE: MemoryStore = MemoryStore::default(); - static ref AGENT: Agent< - CredentialSession< - MemoryStore<(), Object>, - ReqwestClient, - >, - > = Agent::new(CredentialSession::new( - ReqwestClient::new("https://bsky.social"), - MemorySessionStore::default(), - )); + static ref AGENT: Agent>, ReqwestClient>> = + Agent::new(CredentialSession::new( + ReqwestClient::new("https://bsky.social"), + MemorySessionStore::default(), + )); } #[instrument(level = "debug")] - pub async fn get_all_posts() -> Result> - { + pub async fn get_all_posts() -> Result> { let mut i = 0; let mut posts = Vec::new(); - while let Some((cache_creation_time, post)) = - POSTS_CACHE_STORE.get(&i).await? - { + while let Some((cache_creation_time, post)) = POSTS_CACHE_STORE.get(&i).await? { if cache_creation_time.elapsed() > CACHE_INVALIDATION_PERIOD { - tracing::info!( - "Cache for post #{} is stale, fetching new posts", - i - ); + tracing::info!("Cache for post #{} is stale, fetching new posts", i); POSTS_CACHE_STORE.clear().await?; return fetch_posts_into_cache().await; } @@ -62,9 +52,7 @@ pub mod blog { } if posts.is_empty() { - tracing::info!( - "No blog posts found in cache, fetching from ATProto" - ); + tracing::info!("No blog posts found in cache, fetching from ATProto"); return fetch_posts_into_cache().await; } @@ -72,8 +60,7 @@ pub mod blog { } #[instrument(level = "trace")] - async fn fetch_posts_into_cache( - ) -> Result> { + async fn fetch_posts_into_cache() -> Result> { let records = &AGENT .api .com @@ -100,9 +87,7 @@ pub mod blog { .map(|elem| { if let Unknown::Object(btree_map) = &elem.data.value { let ser = serde_json::to_string(&btree_map)?; - let des = serde_json::from_str::< - com::whtwnd::blog::entry::Record, - >(&ser)?; + let des = serde_json::from_str::(&ser)?; return Ok(des); } diff --git a/src/components.rs b/src/components.rs index f6f3111..f738448 100644 --- a/src/components.rs +++ b/src/components.rs @@ -45,10 +45,7 @@ pub trait Component: Send { /// # Returns /// /// * `Result<()>` - An Ok result or an error. - fn register_action_handler( - &mut self, - tx: UnboundedSender, - ) -> Result<()> { + fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { let _ = tx; // to appease clippy Ok(()) } @@ -87,15 +84,10 @@ pub trait Component: Send { /// # Returns /// /// * `Result>` - An action to be processed or none. - fn handle_events( - &mut self, - event: Option, - ) -> Result> { + fn handle_events(&mut self, event: Option) -> Result> { let action = match event { Some(Event::Key(key_event)) => self.handle_key_event(key_event)?, - Some(Event::Mouse(mouse_event)) => { - self.handle_mouse_event(mouse_event)? - } + Some(Event::Mouse(mouse_event)) => self.handle_mouse_event(mouse_event)?, _ => None, }; Ok(action) @@ -122,10 +114,7 @@ pub trait Component: Send { /// # Returns /// /// * `Result>` - An action to be processed or none. - fn handle_mouse_event( - &mut self, - mouse: MouseEvent, - ) -> Result> { + fn handle_mouse_event(&mut self, mouse: MouseEvent) -> Result> { let _ = mouse; // to appease clippy Ok(None) } diff --git a/src/components/blog.rs b/src/components/blog.rs index 092fc35..535b98d 100644 --- a/src/components/blog.rs +++ b/src/components/blog.rs @@ -2,16 +2,14 @@ use std::io::{BufReader, Cursor}; use std::sync::Arc; use color_eyre::eyre::eyre; -use color_eyre::owo_colors::OwoColorize; use color_eyre::Result; use image::{ImageReader, Rgba}; use ratatui::layout::{Constraint, Flex, Layout, Rect, Size}; -use ratatui::style::{Color, Modifier, Style}; -use ratatui::text::{self, Line, Span, Text}; -use ratatui::widgets::{Block, Paragraph, Widget as _, Wrap}; +use ratatui::prelude::*; +use ratatui::widgets::*; use ratatui_image::picker::{Picker, ProtocolType}; use ratatui_image::protocol::StatefulProtocol; -use ratatui_image::{FilterType, FontSize, Resize, StatefulImage}; +use ratatui_image::{Resize, StatefulImage}; use tokio::sync::mpsc::UnboundedSender; use tokio::sync::RwLock; diff --git a/src/components/cat.rs b/src/components/cat.rs index 7f728b1..3079972 100644 --- a/src/components/cat.rs +++ b/src/components/cat.rs @@ -28,10 +28,7 @@ impl Cat { } impl Component for Cat { - fn register_action_handler( - &mut self, - tx: UnboundedSender, - ) -> Result<()> { + fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { self.command_tx = Some(tx); Ok(()) } @@ -57,12 +54,7 @@ impl Component for Cat { .fg(Color::Magenta) .add_modifier(Modifier::SLOW_BLINK | Modifier::BOLD), ), - Rect { - x: area.width - 17, - y: area.height - 4, - width: 16, - height: 6, - }, + Rect { x: area.width - 17, y: area.height - 4, width: 16, height: 6 }, ); Ok(()) diff --git a/src/components/content.rs b/src/components/content.rs index 39c1017..3ae5e56 100644 --- a/src/components/content.rs +++ b/src/components/content.rs @@ -41,11 +41,8 @@ impl Content { .ok_or(eyre!("Failed to create figlet header for about page"))? .to_string(); - let lines: Vec = greetings_header - .trim_end_matches('\n') - .split('\n') - .map(String::from) - .collect(); + let lines: Vec = + greetings_header.trim_end_matches('\n').split('\n').map(String::from).collect(); let mut content = lines .iter() @@ -60,10 +57,7 @@ impl Content { "she/they", Style::default().add_modifier(Modifier::ITALIC), ), - Span::from( - "), and I make scalable systems or something. \ - IDFK.", - ), + Span::from("), and I make scalable systems or something. IDFK."), ]); } Line::raw(format!(" {}", line)) @@ -75,9 +69,7 @@ impl Content { Line::from(""), Line::from(vec![ Span::from(" "), - Span::from( - "I specialize in systems programming, primarily in ", - ), + Span::from("I specialize in systems programming, primarily in "), Span::styled( "Rust 🦀", Style::default() @@ -95,98 +87,79 @@ impl Content { ]), Line::from(""), Line::from( - " I am an avid believer of open-source software, and \ - contribute to a few projects such as:", + " I am an avid believer of open-source software, and contribute to a few \ + projects such as:", ), ]); let projects = vec![ ( - Style::default() - .fg(Color::LightMagenta) - .add_modifier(Modifier::BOLD), + Style::default().fg(Color::LightMagenta).add_modifier(Modifier::BOLD), "lune-org/lune: A standalone Luau runtime", ), ( Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD), - "DiscordLuau/discord-luau: A Luau library for creating \ - Discord bots, powered by Lune", + "DiscordLuau/discord-luau: A Luau library for creating Discord bots, powered \ + by Lune", ), ( Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD), - "pesde-pkg/pesde: A package manager for the Luau programming \ - language, supporting multiple runtimes including Roblox and \ - Lune", + "pesde-pkg/pesde: A package manager for the Luau programming language, \ + supporting multiple runtimes including Roblox and Lune", ), ]; for (style, project) in projects { let parts: Vec<&str> = project.splitn(2, ':').collect(); - let (left, right) = if parts.len() == 2 { - (parts[0], parts[1]) - } else { - (project, "") - }; + let (left, right) = + if parts.len() == 2 { (parts[0], parts[1]) } else { (project, "") }; let formatted_left = Span::styled(left, style); let bullet = " • "; let indent = " "; - let first_line = - if project.len() > area.width as usize - bullet.len() { - let split_point = project - .char_indices() - .take_while(|(i, _)| { - *i < area.width as usize - bullet.len() - }) - .last() - .map(|(i, _)| i) - .unwrap_or(project.len()); - let (first, rest) = project.split_at(split_point); - content.push(Line::from(vec![ - Span::from(bullet), - formatted_left, - Span::from(":"), - Span::styled( - first - .trim_start_matches(format!("{left}:").as_str()) - .to_string(), - Style::default().fg(Color::White), - ), - ])); - rest.to_string() - } else { - content.push(Line::from(vec![ - Span::from(bullet), - formatted_left, - Span::from(":"), - Span::styled( - right.to_string(), - Style::default().fg(Color::White), - ), - ])); - String::new() - }; + let first_line = if project.len() > area.width as usize - bullet.len() { + let split_point = project + .char_indices() + .take_while(|(i, _)| *i < area.width as usize - bullet.len()) + .last() + .map(|(i, _)| i) + .unwrap_or(project.len()); + let (first, rest) = project.split_at(split_point); + content.push(Line::from(vec![ + Span::from(bullet), + formatted_left, + Span::from(":"), + Span::styled( + first.trim_start_matches(format!("{left}:").as_str()).to_string(), + Style::default().fg(Color::White), + ), + ])); + rest.to_string() + } else { + content.push(Line::from(vec![ + Span::from(bullet), + formatted_left, + Span::from(":"), + Span::styled(right.to_string(), Style::default().fg(Color::White)), + ])); + String::new() + }; let mut remaining_text = first_line; while !remaining_text.is_empty() { if remaining_text.len() > area.width as usize - indent.len() { let split_point = remaining_text .char_indices() - .take_while(|(i, _)| { - *i < area.width as usize - indent.len() - }) + .take_while(|(i, _)| *i < area.width as usize - indent.len()) .last() .map(|(i, _)| i) .unwrap_or(remaining_text.len()); let (first, rest) = remaining_text.split_at(split_point); content.push(Line::from(vec![ Span::from(indent), - Span::styled( - first.to_string(), - Style::default().fg(Color::White), - ), + Span::styled(first.to_string(), Style::default().fg(Color::White)), ])); remaining_text = rest.to_string(); } else { @@ -205,8 +178,8 @@ impl Content { content.extend(vec![ Line::from(""), Line::from( - " I am also a fan of the 8 bit aesthetic and think seals are \ - super adorable :3", + " I am also a fan of the 8 bit aesthetic and think seals are super adorable \ + :3", ), ]); @@ -230,10 +203,7 @@ impl Content { } impl Component for Content { - fn register_action_handler( - &mut self, - tx: UnboundedSender, - ) -> Result<()> { + fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { self.command_tx = Some(tx); Ok(()) } @@ -263,9 +233,7 @@ impl Component for Content { // Create the border lines let mut border_top = Line::default(); - border_top - .spans - .push(Span::styled("╭", Style::default().fg(Color::DarkGray))); + border_top.spans.push(Span::styled("╭", Style::default().fg(Color::DarkGray))); let devcomp_width = 13; border_top.spans.push(Span::styled( @@ -277,17 +245,11 @@ impl Component for Content { let mut current_pos = 1 + devcomp_width; for (i, &tab) in tabs.iter().enumerate() { - let (char, style) = - if i == self.selected_tab.load(Ordering::Relaxed) { - ( - "━", - Style::default() - .fg(Color::Magenta) - .add_modifier(Modifier::BOLD), - ) - } else { - ("─", Style::default().fg(Color::DarkGray)) - }; + let (char, style) = if i == self.selected_tab.load(Ordering::Relaxed) { + ("━", Style::default().fg(Color::Magenta).add_modifier(Modifier::BOLD)) + } else { + ("─", Style::default().fg(Color::DarkGray)) + }; let default_style = Style::default().fg(Color::DarkGray); @@ -305,19 +267,15 @@ impl Component for Content { Style::default().fg(Color::DarkGray), )); - border_top - .spans - .push(Span::styled("╮", Style::default().fg(Color::DarkGray))); + border_top.spans.push(Span::styled("╮", Style::default().fg(Color::DarkGray))); let border_bottom = Line::from(Span::styled( "╰".to_owned() + &"─".repeat(area.width as usize - 2) + "╯", Style::default().fg(Color::DarkGray), )); - let border_left = - Span::styled("│", Style::default().fg(Color::DarkGray)); - let border_right = - Span::styled("│", Style::default().fg(Color::DarkGray)); + let border_left = Span::styled("│", Style::default().fg(Color::DarkGray)); + let border_right = Span::styled("│", Style::default().fg(Color::DarkGray)); // Render the content let content_widget = Paragraph::new(content) @@ -342,12 +300,7 @@ impl Component for Content { frame.render_widget( Paragraph::new(border_bottom), - Rect { - x: area.x, - y: area.y + area.height - 1, - width: area.width, - height: 1, - }, + Rect { x: area.x, y: area.y + area.height - 1, width: area.width, height: 1 }, ); for i in 1..area.height - 1 { @@ -358,12 +311,7 @@ impl Component for Content { frame.render_widget( Paragraph::new(Line::from(border_right.clone())), - Rect { - x: area.x + area.width - 1, - y: area.y + i, - width: 1, - height: 1, - }, + Rect { x: area.x + area.width - 1, y: area.y + i, width: 1, height: 1 }, ); } diff --git a/src/components/selection_list.rs b/src/components/selection_list.rs index 5a81b90..3b8fcac 100644 --- a/src/components/selection_list.rs +++ b/src/components/selection_list.rs @@ -1,8 +1,7 @@ use chrono::DateTime; use color_eyre::eyre::Result; -use ratatui::style::{Color, Modifier, Style}; -use ratatui::text::{Line, Span}; -use ratatui::widgets::{Block, Borders, List, ListItem, ListState}; +use ratatui::prelude::*; +use ratatui::widgets::*; use tokio::sync::mpsc::UnboundedSender; use crate::action::Action; @@ -100,8 +99,13 @@ impl Component for SelectionList { ]; let subtitle_span = Span::raw( - [" ", post.subtitle.as_ref().unwrap_or(&super::truncate(post.content.as_ref(), 40))] - .concat(), + [ + " ", + post.subtitle + .as_ref() + .unwrap_or(&super::truncate(post.content.as_ref(), 40)), + ] + .concat(), ); list_content.push(Line::from([line_format.as_slice(), &[subtitle_span]].concat())); diff --git a/src/components/tabs.rs b/src/components/tabs.rs index da41e28..b0ba9d5 100644 --- a/src/components/tabs.rs +++ b/src/components/tabs.rs @@ -19,10 +19,7 @@ pub struct Tabs { } impl Tabs { - pub fn new( - tabs: Vec<&'static str>, - selected_tab: Arc, - ) -> Self { + pub fn new(tabs: Vec<&'static str>, selected_tab: Arc) -> Self { Self { tabs, selected_tab, ..Default::default() } } @@ -44,10 +41,7 @@ impl Tabs { } impl Component for Tabs { - fn register_action_handler( - &mut self, - tx: UnboundedSender, - ) -> Result<()> { + fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { self.command_tx = Some(tx); Ok(()) } @@ -84,17 +78,13 @@ impl Component for Tabs { Style::default().fg(Color::DarkGray), )); - tab_lines[1] - .spans - .push(Span::styled("│", Style::default().fg(Color::DarkGray))); + tab_lines[1].spans.push(Span::styled("│", Style::default().fg(Color::DarkGray))); tab_lines[1].spans.push(Span::styled(format!(" {} ", tab), style)); - tab_lines[1] - .spans - .push(Span::styled("│", Style::default().fg(Color::DarkGray))); + tab_lines[1].spans.push(Span::styled("│", Style::default().fg(Color::DarkGray))); } - let tabs_widget = Paragraph::new(tab_lines) - .block(Block::default().borders(Borders::NONE)); + let tabs_widget = + Paragraph::new(tab_lines).block(Block::default().borders(Borders::NONE)); frame.render_widget( tabs_widget, diff --git a/src/config.rs b/src/config.rs index 0a71cdd..ccdeb68 100644 --- a/src/config.rs +++ b/src/config.rs @@ -38,16 +38,11 @@ pub struct Config { } lazy_static! { - pub static ref PROJECT_NAME: String = - env!("CARGO_CRATE_NAME").to_uppercase().to_string(); + pub static ref PROJECT_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string(); pub static ref DATA_FOLDER: Option = - env::var(format!("{}_DATA", PROJECT_NAME.clone())) - .ok() - .map(PathBuf::from); + env::var(format!("{}_DATA", PROJECT_NAME.clone())).ok().map(PathBuf::from); pub static ref CONFIG_FOLDER: Option = - env::var(format!("{}_CONFIG", PROJECT_NAME.clone())) - .ok() - .map(PathBuf::from); + env::var(format!("{}_CONFIG", PROJECT_NAME.clone())).ok().map(PathBuf::from); } impl Config { @@ -68,19 +63,15 @@ impl Config { ]; let mut found_config = false; for (file, format) in &config_files { - let source = config::File::from(config_dir.join(file)) - .format(*format) - .required(false); + let source = + config::File::from(config_dir.join(file)).format(*format).required(false); builder = builder.add_source(source); if config_dir.join(file).exists() { found_config = true } } if !found_config { - error!( - "No configuration file found. Application may not behave as \ - expected" - ); + error!("No configuration file found. Application may not behave as expected"); } let mut cfg: Self = builder.build()?.try_deserialize()?; @@ -135,18 +126,14 @@ impl<'de> Deserialize<'de> for KeyBindings { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - let parsed_map = HashMap::>::deserialize( - deserializer, - )?; + let parsed_map = HashMap::>::deserialize(deserializer)?; let keybindings = parsed_map .into_iter() .map(|(mode, inner_map)| { let converted_inner_map = inner_map .into_iter() - .map(|(key_str, cmd)| { - (parse_key_sequence(&key_str).unwrap(), cmd) - }) + .map(|(key_str, cmd)| (parse_key_sequence(&key_str).unwrap(), cmd)) .collect(); (mode, converted_inner_map) }) @@ -301,9 +288,7 @@ pub fn key_event_to_string(key_event: &KeyEvent) -> String { } pub fn parse_key_sequence(raw: &str) -> Result, String> { - if raw.chars().filter(|c| *c == '>').count() - != raw.chars().filter(|c| *c == '<').count() - { + if raw.chars().filter(|c| *c == '>').count() != raw.chars().filter(|c| *c == '<').count() { return Err(format!("Unable to parse `{}`", raw)); } let raw = if !raw.contains("><") { @@ -336,9 +321,7 @@ impl<'de> Deserialize<'de> for Styles { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - let parsed_map = HashMap::>::deserialize( - deserializer, - )?; + let parsed_map = HashMap::>::deserialize(deserializer)?; let styles = parsed_map .into_iter() @@ -405,16 +388,12 @@ fn parse_color(s: &str) -> Option { let c = s.trim_start_matches("color").parse::().unwrap_or_default(); Some(Color::Indexed(c)) } else if s.contains("gray") { - let c = 232 - + s.trim_start_matches("gray").parse::().unwrap_or_default(); + let c = 232 + s.trim_start_matches("gray").parse::().unwrap_or_default(); Some(Color::Indexed(c)) } else if s.contains("rgb") { - let red = - (s.as_bytes()[3] as char).to_digit(10).unwrap_or_default() as u8; - let green = - (s.as_bytes()[4] as char).to_digit(10).unwrap_or_default() as u8; - let blue = - (s.as_bytes()[5] as char).to_digit(10).unwrap_or_default() as u8; + let red = (s.as_bytes()[3] as char).to_digit(10).unwrap_or_default() as u8; + let green = (s.as_bytes()[4] as char).to_digit(10).unwrap_or_default() as u8; + let blue = (s.as_bytes()[5] as char).to_digit(10).unwrap_or_default() as u8; let c = 16 + red * 36 + green * 6 + blue; Some(Color::Indexed(c)) } else if s == "bold black" { @@ -487,8 +466,7 @@ mod tests { #[test] fn test_process_color_string() { - let (color, modifiers) = - process_color_string("underline bold inverse gray"); + let (color, modifiers) = process_color_string("underline bold inverse gray"); assert_eq!(color, "gray"); assert!(modifiers.contains(Modifier::UNDERLINED)); assert!(modifiers.contains(Modifier::BOLD)); @@ -562,18 +540,12 @@ mod tests { fn test_multiple_modifiers() { assert_eq!( parse_key_event("ctrl-alt-a").unwrap(), - KeyEvent::new( - KeyCode::Char('a'), - KeyModifiers::CONTROL | KeyModifiers::ALT - ) + KeyEvent::new(KeyCode::Char('a'), KeyModifiers::CONTROL | KeyModifiers::ALT) ); assert_eq!( parse_key_event("ctrl-shift-enter").unwrap(), - KeyEvent::new( - KeyCode::Enter, - KeyModifiers::CONTROL | KeyModifiers::SHIFT - ) + KeyEvent::new(KeyCode::Enter, KeyModifiers::CONTROL | KeyModifiers::SHIFT) ); } diff --git a/src/errors.rs b/src/errors.rs index 2f40166..89760f5 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -21,9 +21,8 @@ pub fn init() -> Result<()> { let metadata = metadata!(); let file_path = handle_dump(&metadata, panic_info); // prints human-panic message - print_msg(file_path, &metadata).expect( - "human-panic: printing error message to console failed", - ); + print_msg(file_path, &metadata) + .expect("human-panic: printing error message to console failed"); eprintln!("{}", panic_hook.panic_report(panic_info)); // prints color-eyre stack trace to stderr } let msg = format!("{}", panic_hook.panic_report(panic_info)); diff --git a/src/keycode.rs b/src/keycode.rs index ba19873..4d85f7b 100644 --- a/src/keycode.rs +++ b/src/keycode.rs @@ -99,15 +99,9 @@ impl KeyCodeExt for KeyCode { fn into_key_event(self) -> KeyEvent { match self { - Self::Char(CTRL_C) => { - KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL) - } - Self::Char(CTRL_D) => { - KeyEvent::new(KeyCode::Char('d'), KeyModifiers::CONTROL) - } - Self::Char(CTRL_Z) => { - KeyEvent::new(KeyCode::Char('z'), KeyModifiers::CONTROL) - } + Self::Char(CTRL_C) => KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL), + Self::Char(CTRL_D) => KeyEvent::new(KeyCode::Char('d'), KeyModifiers::CONTROL), + Self::Char(CTRL_Z) => KeyEvent::new(KeyCode::Char('z'), KeyModifiers::CONTROL), other => KeyEvent::new(other, KeyModifiers::empty()), } } diff --git a/src/landing.rs b/src/landing.rs index c65a0e4..3073829 100644 --- a/src/landing.rs +++ b/src/landing.rs @@ -10,11 +10,7 @@ macro_rules! embedded_route { ($path:expr) => { match WebLandingServer::get($path) { Some(content) => HttpResponse::Ok() - .content_type( - mime_guess::from_path($path) - .first_or_octet_stream() - .as_ref(), - ) + .content_type(mime_guess::from_path($path).first_or_octet_stream().as_ref()) .body(content.data.into_owned()), None => HttpResponse::NotFound().body("404 Not Found"), } @@ -45,11 +41,7 @@ impl WebLandingServer { tracing::info!("Web server listening on {}", addr); HttpServer::new(|| { // TODO: register a default service for a nicer 404 page - App::new() - .service(index) - .service(favicon) - .service(dist) - .wrap(Logger::default()) + App::new().service(index).service(favicon).service(dist).wrap(Logger::default()) }) .bind(addr)? .run() diff --git a/src/logging.rs b/src/logging.rs index 10f5c84..682d6b6 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -30,20 +30,16 @@ pub fn init() -> Result<()> { // // Stage 1: Construct base filter - let env_filter = EnvFilter::builder().with_default_directive( - if cfg!(debug_assertions) { - tracing::Level::DEBUG.into() - } else { - tracing::Level::INFO.into() - }, - ); + let env_filter = EnvFilter::builder().with_default_directive(if cfg!(debug_assertions) { + tracing::Level::DEBUG.into() + } else { + tracing::Level::INFO.into() + }); // Stage 2: Attempt to read from {RUST|CRATE_NAME}_LOG env var or ignore let env_filter = env_filter .try_from_env() - .unwrap_or_else(|_| { - env_filter.with_env_var(LOG_ENV.to_string()).from_env_lossy() - }) + .unwrap_or_else(|_| env_filter.with_env_var(LOG_ENV.to_string()).from_env_lossy()) .add_directive("russh::cipher=info".parse().unwrap()) .add_directive("tui_markdown=info".parse().unwrap()); @@ -86,9 +82,7 @@ pub fn init() -> Result<()> { let layer = layer .compact() .without_time() - .with_span_events( - tracing_subscriber::fmt::format::FmtSpan::NONE, - ) + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::NONE) .with_target(false) .with_thread_ids(false); layer diff --git a/src/main.rs b/src/main.rs index 75b28b3..a3f9c7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,10 +50,8 @@ async fn main() -> Result<()> { crate::logging::init()?; let _ = *OPTIONS; // force clap to run by evaluating it - let ssh_socket_addr = - SSH_SOCKET_ADDR.ok_or(eyre!("Invalid host IP provided"))?; - let web_server_addr = - WEB_SERVER_ADDR.ok_or(eyre!("Invalid host IP provided"))?; + let ssh_socket_addr = SSH_SOCKET_ADDR.ok_or(eyre!("Invalid host IP provided"))?; + let web_server_addr = WEB_SERVER_ADDR.ok_or(eyre!("Invalid host IP provided"))?; tokio::select! { ssh_res = SshServer::start(ssh_socket_addr, ssh_config()) => ssh_res, @@ -68,9 +66,9 @@ pub fn host_ip() -> Result<[u8; 4]> { .host .splitn(4, ".") .map(|octet_str| { - octet_str.parse::().map_err(|_| { - eyre!("Octet component out of range (expected u8)") - }) + octet_str + .parse::() + .map_err(|_| eyre!("Octet component out of range (expected u8)")) }) .collect::>>()?, ) diff --git a/src/ssh.rs b/src/ssh.rs index 688aa60..105c461 100644 --- a/src/ssh.rs +++ b/src/ssh.rs @@ -213,10 +213,7 @@ impl Handler for SshSession { session: &mut Session, ) -> Result<(), Self::Error> { tracing::info!("PTY requested by terminal: {term}"); - tracing::debug!( - "dims: {col_width} * {row_height}, pixel: {pix_width} * \ - {pix_height}" - ); + tracing::debug!("dims: {col_width} * {row_height}, pixel: {pix_width} * {pix_height}"); if pix_width != 0 && pix_height != 0 { self.terminal_info.write().await.set_font_size(( diff --git a/src/tui/backend.rs b/src/tui/backend.rs index e287cd2..1fbc62d 100644 --- a/src/tui/backend.rs +++ b/src/tui/backend.rs @@ -49,9 +49,7 @@ impl Backend for SshBackend { self.inner.show_cursor() } - fn get_cursor_position( - &mut self, - ) -> io::Result { + fn get_cursor_position(&mut self) -> io::Result { self.inner.get_cursor_position() } diff --git a/src/tui/mod.rs b/src/tui/mod.rs index 5606178..89dcc5a 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -7,8 +7,8 @@ use backend::SshBackend; use color_eyre::Result; use crossterm::cursor; use crossterm::event::{ - DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, - EnableMouseCapture, KeyEvent, MouseEvent, + DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture, + KeyEvent, MouseEvent, }; use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen}; use serde::{Deserialize, Serialize}; @@ -118,10 +118,8 @@ impl Tui { tick_rate: f64, frame_rate: f64, ) { - let mut tick_interval = - interval(Duration::from_secs_f64(1.0 / tick_rate)); - let mut render_interval = - interval(Duration::from_secs_f64(1.0 / frame_rate)); + let mut tick_interval = interval(Duration::from_secs_f64(1.0 / tick_rate)); + let mut render_interval = interval(Duration::from_secs_f64(1.0 / frame_rate)); // if this fails, then it's likely a bug in the calling code event_tx.send(Event::Init).expect("failed to send init event"); @@ -162,14 +160,9 @@ impl Tui { }; if timeout(attempt_timeout, self.await_shutdown()).await.is_err() { - timeout(attempt_timeout, abort_shutdown).await.inspect_err( - |_| { - error!( - "Failed to abort task in 100 milliseconds for unknown \ - reason" - ) - }, - )?; + timeout(attempt_timeout, abort_shutdown).await.inspect_err(|_| { + error!("Failed to abort task in 100 milliseconds for unknown reason") + })?; } Ok(()) @@ -178,11 +171,7 @@ impl Tui { pub fn enter(&mut self) -> Result<()> { let mut term = self.terminal.try_lock()?; // crossterm::terminal::enable_raw_mode()?; // TODO: Enable raw mode for pty - crossterm::execute!( - term.backend_mut(), - EnterAlternateScreen, - cursor::Hide - )?; + crossterm::execute!(term.backend_mut(), EnterAlternateScreen, cursor::Hide)?; if self.mouse { crossterm::execute!(term.backend_mut(), EnableMouseCapture)?; @@ -212,11 +201,7 @@ impl Tui { crossterm::execute!(term.backend_mut(), DisableMouseCapture)?; } - crossterm::execute!( - term.backend_mut(), - LeaveAlternateScreen, - cursor::Show - )?; + crossterm::execute!(term.backend_mut(), LeaveAlternateScreen, cursor::Show)?; Ok(()) } @@ -231,8 +216,7 @@ impl Tui { // Update the status and initialize a cancellation token let token = Arc::new(CancellationToken::new()); let suspension = Arc::new(Mutex::new(())); - *self.status.write().await = - TuiStatus::Suspended(Arc::clone(&suspension)); + *self.status.write().await = TuiStatus::Suspended(Arc::clone(&suspension)); // Spawn a task holding on the lock until a notification interrupts it let status = Arc::clone(&self.status); @@ -263,9 +247,7 @@ impl Drop for Tui { block_in_place(|| { let handle = Handle::current(); let _ = handle.block_on(async { - self.exit() - .await - .inspect_err(|err| error!("Failed to exit Tui: {err}")) + self.exit().await.inspect_err(|err| error!("Failed to exit Tui: {err}")) }); }) } diff --git a/src/tui/terminal.rs b/src/tui/terminal.rs index 7c70c0a..080076d 100644 --- a/src/tui/terminal.rs +++ b/src/tui/terminal.rs @@ -1,10 +1,8 @@ use std::default::Default; use default_variant::default; -use ratatui_image::{ - picker::{Capability, ProtocolType}, - FontSize, -}; +use ratatui_image::picker::{Capability, ProtocolType}; +use ratatui_image::FontSize; use serde::{Deserialize, Serialize}; use strum::Display;