diff --git a/fusio/src/impls/disk/opfs/mod.rs b/fusio/src/impls/disk/opfs/mod.rs index 4bded00..1393fad 100644 --- a/fusio/src/impls/disk/opfs/mod.rs +++ b/fusio/src/impls/disk/opfs/mod.rs @@ -27,7 +27,7 @@ where /// OPFS based on [FileSystemWritableFileStream](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream) pub struct OPFSFile { - file_handle: FileSystemFileHandle, + file_handle: Option, write_stream: Option, pos: u64, } @@ -60,14 +60,16 @@ impl OPFSFile { }; Ok(Self { - file_handle, + file_handle: Some(file_handle), write_stream, pos: size.round() as u64, }) } async fn reader(&self, pos: u64, buf_len: u64) -> Result { - let file = promise::(self.file_handle.get_file()).await?; + debug_assert!(self.file_handle.is_some()); + let file_handle = self.file_handle.as_ref().expect("read file after closed."); + let file = promise::(file_handle.get_file()).await?; if (file.size().round() as u64) < pos + buf_len as u64 { return Err(Error::Io(io::Error::new( @@ -76,7 +78,12 @@ impl OPFSFile { ))); } - let blob = file.slice_with_i32(pos as i32).unwrap(); + let blob = if buf_len == 0 { + file.slice_with_i32(pos as i32).unwrap() + } else { + file.slice_with_i32_and_i32(pos as i32, (pos + buf_len) as i32) + .unwrap() + }; blob.stream() .get_reader() .dyn_into::() @@ -97,7 +104,7 @@ impl Write for OPFSFile { match JsFuture::from( self.write_stream .as_ref() - .unwrap() + .expect("write file after closed.") .write_with_u8_array(buf.as_slice()) .unwrap(), ) @@ -114,8 +121,8 @@ impl Write for OPFSFile { /// Close the associated OPFS file. async fn close(&mut self) -> Result<(), Error> { - let writer = self.write_stream.take(); - if let Some(writer) = writer { + let _ = self.file_handle.take(); + if let Some(writer) = self.write_stream.take() { JsFuture::from(writer.close()).await.map_err(wasm_err)?; } Ok(()) @@ -180,7 +187,15 @@ impl Read for OPFSFile { /// Return the size of file in bytes. async fn size(&self) -> Result { - let file = promise::(self.file_handle.get_file()).await?; + debug_assert!(self.file_handle.is_some()); + + let file = promise::( + self.file_handle + .as_ref() + .expect("read file after closed.") + .get_file(), + ) + .await?; Ok(file.size() as u64) } diff --git a/fusio/tests/opfs.rs b/fusio/tests/opfs.rs index f9e0fdc..9453cf6 100644 --- a/fusio/tests/opfs.rs +++ b/fusio/tests/opfs.rs @@ -90,7 +90,10 @@ pub(crate) mod tests { async fn test_opfs_read_write() { let fs = OPFS; let mut file = fs - .open_options(&"file_rw".into(), OpenOptions::default().create(true).truncate(true)) + .open_options( + &"file".into(), + OpenOptions::default().create(true).truncate(true), + ) .await .unwrap(); let (result, _) = file.write_all([1, 2, 3, 4].as_mut()).await; @@ -102,7 +105,7 @@ pub(crate) mod tests { file.close().await.unwrap(); let mut file = fs - .open_options(&"file_rw".into(), OpenOptions::default().create(true)) + .open_options(&"file".into(), OpenOptions::default()) .await .unwrap(); let expected = [1_u8, 2, 3, 4, 11, 23, 34, 47, 121, 93, 94, 97]; @@ -116,14 +119,17 @@ pub(crate) mod tests { let (result, data) = file.read_exact_at(buf.as_mut(), 3).await; result.unwrap(); assert_eq!(data, [4, 11, 23, 34, 47, 121, 93]); - remove_all(&fs, &["file_rw"]).await; + remove_all(&fs, &["file"]).await; } #[wasm_bindgen_test] async fn test_opfs_read_write_utf16() { let fs = OPFS; let mut file = fs - .open_options(&"file_utf16".into(), OpenOptions::default().create(true).truncate(true)) + .open_options( + &"file".into(), + OpenOptions::default().create(true).truncate(true), + ) .await .unwrap(); let utf16_bytes: &[u8] = &[ @@ -136,7 +142,7 @@ pub(crate) mod tests { file.close().await.unwrap(); let mut file = fs - .open_options(&"file_utf16".into(), OpenOptions::default().write(true)) + .open_options(&"file".into(), OpenOptions::default()) .await .unwrap(); let (result, data) = file.read_to_end_at(vec![], 0).await; @@ -149,14 +155,17 @@ pub(crate) mod tests { ] ); - remove_all(&fs, &["file_utf16"]).await; + remove_all(&fs, &["file"]).await; } #[wasm_bindgen_test] async fn test_opfs_read_eof() { let fs = OPFS; let mut file = fs - .open_options(&"file_eof".into(), OpenOptions::default().create(true).truncate(true)) + .open_options( + &"file".into(), + OpenOptions::default().create(true).truncate(true), + ) .await .unwrap(); @@ -169,7 +178,7 @@ pub(crate) mod tests { file.close().await.unwrap(); let mut file = fs - .open_options(&"file_eof".into(), OpenOptions::default().write(true)) + .open_options(&"file".into(), OpenOptions::default()) .await .unwrap(); @@ -177,6 +186,6 @@ pub(crate) mod tests { let (result, data) = file.read_exact_at(buf.as_mut(), 5).await; assert!(result.is_err()); assert_eq!(data, [0]); - remove_all(&fs, &["file_eof"]).await; + remove_all(&fs, &["file"]).await; } }