use std::path::Path; use std::{fs, io}; use crate::operation::OperationError; use super::Controller; // Special reader just for operations, handling cancel and progress pub struct OpReader { file: fs::File, metadata: fs::Metadata, current: u64, controller: Controller, } impl OpReader { pub fn new>(path: P, controller: Controller) -> io::Result { let file = fs::File::open(&path)?; let metadata = file.metadata()?; Ok(Self { file, metadata, current: 0, controller, }) } } impl io::Read for OpReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { cosmic::iced::futures::executor::block_on(async { self.controller .check() .await .map_err(|s| io::Error::other(OperationError::from_state(s, &self.controller))) })?; let count = self.file.read(buf)?; self.current += count as u64; let progress = self.current as f32 / self.metadata.len() as f32; self.controller.set_progress(progress); Ok(count) } }