shrupl/src/file/uploading.rs

96 lines
2.2 KiB
Rust
Raw Normal View History

use std::{
2025-06-08 00:40:29 +00:00
fmt, fs,
io::{self, Read, Seek, SeekFrom},
path::PathBuf,
};
use serde::{Deserialize, Serialize};
use super::{Chunk, FileTrait};
#[derive(Serialize, Deserialize)]
pub struct Uploading {
2025-06-04 16:58:18 +00:00
path: PathBuf,
2025-06-06 23:42:18 +00:00
size: u64,
patch_uri: String,
last_offset: Option<u64>,
2025-06-06 23:42:18 +00:00
offset: u64,
}
impl fmt::Debug for Uploading {
2025-06-08 00:40:29 +00:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2025-06-05 01:13:54 +00:00
write!(
f,
"Uploading {:?} ({}/{})",
2025-06-05 01:45:25 +00:00
self.path.display(),
self.offset,
self.size
2025-06-05 01:13:54 +00:00
)
}
}
impl Uploading {
pub(super) fn new(path: PathBuf, size: u64, patch_uri: String) -> Self {
2025-06-04 16:58:18 +00:00
Self {
path,
size,
patch_uri,
last_offset: None,
2025-06-04 16:58:18 +00:00
offset: 0,
}
}
2025-06-06 23:42:18 +00:00
pub fn get_offset(&self) -> u64 {
self.offset
}
pub fn rewind(self) -> Option<Self> {
self.last_offset.map(|last_offset| Self {
last_offset: None,
offset: last_offset,
..self
})
}
pub fn read<'t>(&mut self, buf: &'t mut [u8]) -> io::Result<Chunk<'t>> {
2025-06-05 22:08:24 +00:00
let mut f = fs::File::open(&self.path)?;
f.seek(SeekFrom::Start(self.offset))?;
let read_len = f.read(buf)?;
if read_len == 0 {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
format!("could not read from file {:?}", self.path.display()),
));
}
let chunk = Chunk::new(&buf[..read_len], self.patch_uri.clone(), self.offset);
self.last_offset = Some(self.offset);
self.offset += chunk.get_length();
Ok(chunk)
}
pub fn check_eof(self) -> Result<Self, PathBuf> {
if self.offset < self.size {
Ok(self)
} else {
Err(self.path)
}
}
}
2025-06-06 15:21:49 +00:00
impl<'t> FileTrait<'t> for Uploading {
/// get a reference to the file's name
///
/// Uses `SharryFile::extract_file_name`, which may **panic**!
2025-06-06 23:42:18 +00:00
fn get_name(&'t self) -> &'t str {
<Self as FileTrait>::extract_file_name(&self.path)
2025-06-06 15:21:49 +00:00
}
2025-06-06 23:42:18 +00:00
fn get_size(&self) -> u64 {
self.size
2025-06-06 15:21:49 +00:00
}
}