From 52888b4f94eacb5a5f5cb6c8f8deab1241add7c2 Mon Sep 17 00:00:00 2001 From: Kould Date: Fri, 15 Nov 2024 19:18:34 +0800 Subject: [PATCH] chore: move copy to dynamic --- fusio/src/dynamic/fs.rs | 47 +++++++++++++++++++++++++++++++++++++++-- fusio/src/fs/mod.rs | 38 +-------------------------------- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/fusio/src/dynamic/fs.rs b/fusio/src/dynamic/fs.rs index 939ff79..5d96bf2 100644 --- a/fusio/src/dynamic/fs.rs +++ b/fusio/src/dynamic/fs.rs @@ -1,11 +1,11 @@ -use std::pin::Pin; +use std::{cmp, pin::Pin, sync::Arc}; use futures_core::Stream; use super::MaybeSendFuture; use crate::{ buf::IoBufMut, - fs::{FileMeta, Fs, OpenOptions}, + fs::{FileMeta, FileSystemTag, Fs, OpenOptions}, path::Path, DynRead, DynWrite, Error, IoBuf, MaybeSend, MaybeSync, Read, Write, }; @@ -48,6 +48,8 @@ impl<'write> Write for Box { } pub trait DynFs: MaybeSend + MaybeSync { + fn file_system(&self) -> FileSystemTag; + fn open<'s, 'path: 's>( &'s self, path: &'path Path, @@ -99,6 +101,10 @@ pub trait DynFs: MaybeSend + MaybeSync { } impl DynFs for F { + fn file_system(&self) -> FileSystemTag { + Fs::file_system(self) + } + fn open_options<'s, 'path: 's>( &'s self, path: &'path Path, @@ -160,6 +166,43 @@ impl DynFs for F { } } +pub async fn copy( + from_fs: &Arc, + from: &Path, + to_fs: &Arc, + to: &Path, +) -> Result<(), Error> { + if from_fs.file_system() == to_fs.file_system() { + from_fs.copy(from, to).await?; + return Ok(()); + } + let mut from_file = from_fs + .open_options(from, OpenOptions::default().read(true)) + .await?; + let from_file_size = DynRead::size(&from_file).await? as usize; + + let mut to_file = to_fs + .open_options(to, OpenOptions::default().create(true).write(true)) + .await?; + let buf_size = cmp::min(from_file_size, 4 * 1024); + let mut buf = Some(vec![0u8; buf_size]); + let mut read_pos = 0u64; + + while (read_pos as usize) < from_file_size - 1 { + let tmp = buf.take().unwrap(); + let (result, tmp) = Read::read_exact_at(&mut from_file, tmp, read_pos).await; + result?; + read_pos += tmp.bytes_init() as u64; + + let (result, tmp) = Write::write_all(&mut to_file, tmp).await; + result?; + buf = Some(tmp); + } + DynWrite::close(&mut to_file).await?; + + Ok(()) +} + #[cfg(test)] mod tests { diff --git a/fusio/src/fs/mod.rs b/fusio/src/fs/mod.rs index 9792629..95cc6e0 100644 --- a/fusio/src/fs/mod.rs +++ b/fusio/src/fs/mod.rs @@ -3,7 +3,7 @@ mod options; -use std::{cmp, future::Future}; +use std::future::Future; use futures_core::Stream; pub use options::*; @@ -55,42 +55,6 @@ pub trait Fs: MaybeSend + MaybeSync { fn link(&self, from: &Path, to: &Path) -> impl Future> + MaybeSend; } -pub async fn copy(from_fs: &F, from: &Path, to_fs: &T, to: &Path) -> Result<(), Error> -where - F: Fs, - T: Fs, -{ - if from_fs.file_system() == to_fs.file_system() { - from_fs.copy(from, to).await?; - return Ok(()); - } - let mut from_file = from_fs - .open_options(from, OpenOptions::default().read(true)) - .await?; - let from_file_size = from_file.size().await? as usize; - - let mut to_file = to_fs - .open_options(to, OpenOptions::default().create(true).write(true)) - .await?; - let buf_size = cmp::min(from_file_size, 4 * 1024); - let mut buf = Some(vec![0u8; buf_size]); - let mut read_pos = 0u64; - - while (read_pos as usize) < from_file_size - 1 { - let tmp = buf.take().unwrap(); - let (result, tmp) = from_file.read_exact_at(tmp, read_pos).await; - result?; - read_pos += tmp.len() as u64; - - let (result, tmp) = to_file.write_all(tmp).await; - result?; - buf = Some(tmp); - } - to_file.close().await?; - - Ok(()) -} - #[cfg(test)] mod tests {