use std::path::PathBuf;
use std::sync::mpsc;
use std::thread;
use anyhow::Result;
use crate::modes::{Preview, PreviewBuilder};
enum RequestKind {
PreviewRequest(PreviewRequest),
Quit,
}
struct PreviewRequest {
path: PathBuf,
tab_index: usize,
line_nr: Option<usize>,
}
impl PreviewRequest {
fn new(path: PathBuf, tab_index: usize, line_nr: Option<usize>) -> Self {
Self {
path,
tab_index,
line_nr,
}
}
}
pub struct PreviewResponse {
pub path: PathBuf,
pub tab_index: usize,
pub line_nr: Option<usize>,
pub preview: Preview,
}
impl PreviewResponse {
fn new(path: PathBuf, tab_index: usize, line_nr: Option<usize>, preview: Preview) -> Self {
Self {
path,
tab_index,
line_nr,
preview,
}
}
}
pub struct Previewer {
tx_request: mpsc::Sender<RequestKind>,
}
impl Previewer {
pub fn new(tx_preview: mpsc::Sender<PreviewResponse>) -> Self {
let (tx_request, rx_request) = mpsc::channel::<RequestKind>();
thread::spawn(move || {
while let Some(request) = rx_request.iter().next() {
match request {
RequestKind::PreviewRequest(PreviewRequest {
path,
tab_index,
line_nr,
}) => {
if let Ok(preview) = PreviewBuilder::new(&path).build() {
tx_preview
.send(PreviewResponse::new(path, tab_index, line_nr, preview))
.unwrap();
};
}
RequestKind::Quit => break,
}
}
});
Self { tx_request }
}
pub fn quit(&self) {
crate::log_info!("stopping previewer loop");
match self.tx_request.send(RequestKind::Quit) {
Ok(()) => (),
Err(e) => crate::log_info!("Previewer::quit error {e:?}"),
};
}
pub fn build(&self, path: PathBuf, index: usize, line_index: Option<usize>) -> Result<()> {
self.tx_request
.send(RequestKind::PreviewRequest(PreviewRequest::new(
path, index, line_index,
)))?;
Ok(())
}
}