feat: add file peaking, 1.5.0

This commit is contained in:
DecDuck
2025-07-02 18:03:35 +10:00
parent 7c3e6fe63c
commit 8f4b2a6c6d
7 changed files with 129 additions and 145 deletions

View File

@@ -3,7 +3,7 @@ use core::arch;
use std::os::unix::fs::PermissionsExt;
use std::{
fs::File,
io::{self, Read},
io::{self, Read, Seek},
path::PathBuf,
pin::Pin,
rc::Rc,
@@ -50,6 +50,7 @@ impl VersionBackend for PathVersionBackend {
results.push(VersionFile {
relative_filename: relative.to_string_lossy().to_string(),
permission: permissions,
size: metadata.len(),
});
}
@@ -89,7 +90,7 @@ impl Drop for ZipVersionBackend {
}
}
struct ZipFileWrapper {
pub struct ZipFileWrapper {
pub archive: Arc<ZipArchive<FileReader>>,
wayfinder: ZipArchiveEntryWayfinder,
offset: u64,
@@ -109,12 +110,7 @@ impl Read for ZipFileWrapper {
}
impl Skippable for ZipFileWrapper {
fn skip(&mut self, amount: u64) {
/*io::copy(
&mut self.inner.reader().by_ref().take(amount),
&mut io::sink(),
)
.unwrap();
*/
self.offset += amount;
}
}
impl MinimumFileObject for ZipFileWrapper {}
@@ -131,6 +127,7 @@ impl VersionBackend for ZipVersionBackend {
results.push(VersionFile {
relative_filename: entry.file_safe_path().unwrap().to_string(),
permission: 744, // apparently ZIPs with permissions are not supported by this library, so we let the owner do anything
size: entry.uncompressed_size_hint(),
});
}
results

View File

@@ -4,10 +4,11 @@ use std::{
use tokio::io::{self, AsyncRead};
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct VersionFile {
pub relative_filename: String,
pub permission: u32,
pub size: u64,
}
pub trait Skippable {

View File

@@ -60,6 +60,23 @@ pub fn list_files(path: String) -> Result<Vec<String>> {
Ok(files.into_iter().map(|e| e.relative_filename).collect())
}
/**
* This is inefficient, but is used in attempt to keep the interface simple
*/
#[napi]
pub fn peek_file(path: String, sub_path: String) -> Result<u32> {
let path = Path::new(&path);
let mut backend =
create_backend_for_path(path).ok_or(napi::Error::from_reason("No backend for path"))?;
let files = backend.list_files();
let file = files
.iter()
.find(|e| e.relative_filename == sub_path)
.ok_or(napi::Error::from_reason("Can't find file to peek"))?;
return Ok(file.size.try_into().unwrap());
}
#[napi]
pub fn read_file(
path: String,
@@ -73,6 +90,7 @@ pub fn read_file(
let version_file = VersionFile {
relative_filename: sub_path,
permission: 0, // Shouldn't matter
size: 0, // Shouldn't matter
};
// Use `?` operator for cleaner error propagation from `Option`
let mut reader = backend.reader(&version_file)?;
@@ -87,10 +105,13 @@ pub fn read_file(
let amount = limit - start.or(Some(0)).unwrap();
ReadToAsyncRead {
inner: Box::new(reader.take(amount.into())),
backend
backend,
}
} else {
ReadToAsyncRead { inner: reader, backend }
ReadToAsyncRead {
inner: reader,
backend,
}
};
// Create a FramedRead stream with BytesCodec for chunking