diff --git a/src/converter.rs b/src/converter.rs index ada5e52..fd842fd 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -1,7 +1,10 @@ use image::ImageFormat; use itertools::Itertools; use ratatui_image::{picker::Picker, protocol::Protocol, Resize}; -use tokio::sync::mpsc::{error::{SendError, TryRecvError}, UnboundedReceiver, UnboundedSender}; +use tokio::sync::mpsc::{ + error::{SendError, TryRecvError}, + UnboundedReceiver, UnboundedSender +}; use crate::renderer::{fill_default, PageInfo, RenderError}; @@ -34,7 +37,7 @@ pub async fn run_conversion_loop( iteration: &mut usize ) -> Result, RenderError> { if images.is_empty() || *iteration >= MAX_ITER { - return Ok(None) + return Ok(None); } // This kinda mimics the way the renderer alternates between going above and below the @@ -50,20 +53,28 @@ pub async fn run_conversion_loop( .skip(*iteration) .find_map(|(i_idx, p_idx)| images[p_idx].take().map(|p| (p, i_idx))) else { - return Ok(None) + return Ok(None); }; let img_area = page_info.img_data.area; - let dyn_img = image::load_from_memory_with_format(&page_info.img_data.data, ImageFormat::Png) - .map_err(|e| RenderError::Render(format!("Couldn't convert Vec to DynamicImage: {e}")))?; + let dyn_img = + image::load_from_memory_with_format(&page_info.img_data.data, ImageFormat::Png) + .map_err(|e| { + RenderError::Render(format!("Couldn't convert Vec to DynamicImage: {e}")) + })?; // We don't actually want to Crop this image, but we've already // verified (with the ImageSurface stuff) that the image is the correct // size for the area given, so to save ratatui the work of having to // resize it, we tell them to crop it to fit. - let txt_img = picker.new_protocol(dyn_img, img_area, Resize::Crop) - .map_err(|e| RenderError::Render(format!("Couldn't convert DynamicImage to ratatui image: {e}")))?; + let txt_img = picker + .new_protocol(dyn_img, img_area, Resize::Crop) + .map_err(|e| { + RenderError::Render(format!( + "Couldn't convert DynamicImage to ratatui image: {e}" + )) + })?; // update the iteration to the iteration that we stole this image from *iteration = new_iter; @@ -75,21 +86,17 @@ pub async fn run_conversion_loop( })) } - fn handle_notif( - msg: ConverterMsg, - images: &mut Vec>, - page: &mut usize - ) { + fn handle_notif(msg: ConverterMsg, images: &mut Vec>, page: &mut usize) { match msg { ConverterMsg::AddImg(img) => { let page_num = img.page; images[page_num] = Some(img); - }, + } ConverterMsg::NumPages(n_pages) => { fill_default(images, n_pages); *page = (*page).min(n_pages - 1); - }, - ConverterMsg::GoToPage(new_page) => *page = new_page, + } + ConverterMsg::GoToPage(new_page) => *page = new_page } } @@ -100,7 +107,7 @@ pub async fn run_conversion_loop( Ok(msg) => { handle_notif(msg, &mut images, &mut page); continue 'outer; - }, + } Err(TryRecvError::Empty) => (), Err(TryRecvError::Disconnected) => panic!("Disconnected :(") } diff --git a/src/main.rs b/src/main.rs index 611ab56..2a24479 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,17 +6,17 @@ use converter::{run_conversion_loop, ConvertedPage, ConverterMsg}; use crossterm::{ execute, terminal::{ - disable_raw_mode, enable_raw_mode, window_size, EndSynchronizedUpdate, EnterAlternateScreen, LeaveAlternateScreen + disable_raw_mode, enable_raw_mode, window_size, EndSynchronizedUpdate, + EnterAlternateScreen, LeaveAlternateScreen } }; -use futures_util::stream::StreamExt; +use futures_util::{stream::StreamExt, FutureExt}; use glib::{LogField, LogLevel, LogWriterOutput}; use notify::{RecursiveMode, Watcher}; use ratatui::{backend::CrosstermBackend, Terminal}; use ratatui_image::picker::Picker; use renderer::{RenderInfo, RenderNotif}; use tui::{InputAction, Tui}; -use futures_util::FutureExt; mod converter; mod renderer; @@ -39,9 +39,7 @@ async fn main() -> Result<(), Box> { // This shouldn't fail to send unless the receiver gets disconnected. If that's happened, // then like the main thread has panicked or something, so it doesn't matter if this panics // as well - watch_tx - .send(renderer::RenderNotif::Reload) - .unwrap(); + watch_tx.send(renderer::RenderNotif::Reload).unwrap(); })?; // We're making this nonrecursive 'cause we're just watching a single file, so there's nothing @@ -55,13 +53,18 @@ async fn main() -> Result<(), Box> { // We need to create `picker` on this thread because if we create it on the `renderer` thread, // it messes up something with user input. Input never makes it to the crossterm thing - let mut picker = Picker::new((window_size.width / window_size.columns, window_size.height / window_size.rows)); + let mut picker = Picker::new(( + window_size.width / window_size.columns, + window_size.height / window_size.rows + )); picker.guess_protocol(); // then we want to spawn off the rendering task // We need to use the thread::spawn API so that this exists in a thread not owned by tokio, // since the methods we call in `start_rendering` will panic if called in an async context - std::thread::spawn(move || renderer::start_rendering(file_path, render_tx, render_rx, window_size)); + std::thread::spawn(move || { + renderer::start_rendering(file_path, render_tx, render_rx, window_size) + }); let mut ev_stream = crossterm::event::EventStream::new(); diff --git a/src/renderer.rs b/src/renderer.rs index 6093ddd..e7eb9b5 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -89,9 +89,7 @@ pub fn start_rendering( }; let n_pages = doc.n_pages() as usize; - sender - .send(Ok(RenderInfo::NumPages(n_pages))) - .unwrap(); + sender.send(Ok(RenderInfo::NumPages(n_pages))).unwrap(); // We're using this vec of bools to indicate which page numbers have already been rendered, // to support people jumping to specific pages and having quick rendering results. We @@ -204,7 +202,14 @@ pub fn start_rendering( rendered.successful && rendered.contained_term == Some(false); // render the page - match render_single_page(page, area, num, &search_term, rendered_with_no_results, &size) { + match render_single_page( + page, + area, + num, + &search_term, + rendered_with_no_results, + &size + ) { // If we've already rendered it just fine and we don't need to render it again, // just continue. We're all good Ok(None) => (), @@ -216,7 +221,7 @@ pub fn start_rendering( rendered.contained_term = Some(img.search_results > 0); rendered.successful = true; sender.send(Ok(RenderInfo::Page(img))).unwrap() - }, + } // And if we got an error, then obviously we need to propagate that Err(e) => sender.send(Err(RenderError::Render(e))).unwrap() } @@ -279,9 +284,9 @@ fn render_single_page( // scale the height to fit perfectly. The dimension that _is not_ scaled to fit perfectly // is scaled by the same factor as the dimension that _is_ scaled perfectly. let scale_factor = if p_aspect_ratio > area_aspect_ratio { - area_full_w as f64 / p_width + area_full_w / p_width } else { - area_full_h as f64 / p_height + area_full_h / p_height }; let surface_width = p_width * scale_factor; diff --git a/src/tui.rs b/src/tui.rs index 58180df..89f8662 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -348,10 +348,13 @@ impl Tui { term.push(c); Some(InputAction::Redraw) } - KeyCode::Backspace if let BottomMessage::Input(InputCommand::Search(ref mut term)) = self.bottom_msg => { + KeyCode::Backspace + if let BottomMessage::Input(InputCommand::Search(ref mut term)) = + self.bottom_msg => + { term.pop(); Some(InputAction::Redraw) - }, + } KeyCode::Char(c) if let BottomMessage::Input(InputCommand::GoToPage(ref mut page)) = self.bottom_msg =>