46 lines
1.1 KiB
Rust
46 lines
1.1 KiB
Rust
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<P: AsRef<Path>>(path: P, controller: Controller) -> io::Result<Self> {
|
|
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<usize> {
|
|
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)
|
|
}
|
|
}
|