diff --git a/.gitignore b/.gitignore index d002fce..5dd689d 100644 --- a/.gitignore +++ b/.gitignore @@ -201,4 +201,7 @@ test.mjs manifest.json # JetBrains -.idea \ No newline at end of file +.idea + + +TESTFILE diff --git a/index.d.ts b/index.d.ts index 1626a26..6b181bf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -5,7 +5,7 @@ function hasBackendForPath(path: string): boolean function listFiles(path: string): Array -function readFile(path: string, subPath: string): ReadableStream> | null +function readFile(path: string, subPath: string): ReadableStream | null function callAltThreadFunc(tsfn: ((err: Error | null, ) => any)): void function generateManifest(dir: string, progressSfn: ((err: Error | null, arg: number) => any), logSfn: ((err: Error | null, arg: string) => any), callbackSfn: ((err: Error | null, arg: string) => any)): void function generateRootCa(): Array diff --git a/src/file_utils.rs b/src/file_utils.rs index d2152a7..bd4d126 100644 --- a/src/file_utils.rs +++ b/src/file_utils.rs @@ -2,13 +2,19 @@ use std::os::unix::fs::PermissionsExt; use std::{ fs::{self, metadata, File}, - io::{BufReader, Read}, + io::{self, BufReader, ErrorKind, Read}, path::{Path, PathBuf}, task::Poll, }; -use napi::{bindgen_prelude::*, tokio_stream::{Stream, StreamExt}}; -use tokio_util::{bytes::BytesMut, codec::{BytesCodec, FramedRead}}; +use napi::{ + bindgen_prelude::*, + tokio_stream::{Stream, StreamExt}, +}; +use tokio_util::{ + bytes::BytesMut, + codec::{BytesCodec, FramedRead}, +}; fn _list_files(vec: &mut Vec, path: &Path) { if metadata(path).unwrap().is_dir() { @@ -128,21 +134,32 @@ pub fn read_file( path: String, sub_path: String, env: &Env, -) -> Option>> { +) -> Option>> { let path = Path::new(&path); let backend = create_backend_for_path(path).unwrap(); let version_file = VersionFile { relative_filename: sub_path, permission: 0, // Shouldn't matter }; + // Use `?` operator for cleaner error propagation from `Option` let reader = backend.reader(&version_file)?; + + // Convert std::fs::File to tokio::fs::File for async operations let reader = tokio::fs::File::from_std(reader); - let stream = FramedRead::new(reader, BytesCodec::new()).map(|e| { - if let Ok(bytes) = e { - Ok(bytes.to_vec()) - } else { - Err(napi::Error::from_reason(e.unwrap_err().to_string())) - } - }); + + // Create a FramedRead stream with BytesCodec for chunking + + let stream = FramedRead::new(reader, BytesCodec::new()) + // Use StreamExt::map to transform each Result item + .map(|result_item| { + result_item + // Apply Result::map to transform Ok(BytesMut) to Ok(Vec) + .map(|bytes| bytes.to_vec()) + // Apply Result::map_err to transform Err(std::io::Error) to Err(napi::Error) + .map_err(|e| napi::Error::from(e)) // napi::Error implements From + }); + // Create the napi-rs ReadableStream from the tokio_stream::Stream + // The unwrap() here means if stream creation fails, it will panic. + // For a production system, consider returning Result> and handling this. Some(ReadableStream::create_with_stream_bytes(env, stream).unwrap()) }