diff --git a/src/gio/file_output_stream.rs b/src/gio/file_output_stream.rs index 7d9415c..c915b2f 100644 --- a/src/gio/file_output_stream.rs +++ b/src/gio/file_output_stream.rs @@ -7,6 +7,14 @@ use gio::{ }; use glib::{Bytes, Priority, object::IsA}; +/// Mutable bytes count +pub struct Size { + pub chunk: usize, + /// `None` for unlimited + pub limit: Option, + pub total: usize, +} + /// Asynchronously move all bytes from [IOStream](https://docs.gtk.org/gio/class.IOStream.html) /// to [FileOutputStream](https://docs.gtk.org/gio/class.FileOutputStream.html) /// * require `IOStream` reference to keep `Connection` active in async thread @@ -15,59 +23,50 @@ pub fn from_stream_async( file_output_stream: FileOutputStream, cancellable: Cancellable, priority: Priority, - (chunk, limit, mut total): ( - usize, // bytes_in_chunk - Option, // bytes_total_limit, `None` to unlimited - usize, // bytes_total - ), + mut size: Size, (on_chunk, on_complete): ( impl Fn(Bytes, usize) + 'static, // on_chunk impl FnOnce(Result<(FileOutputStream, usize), Error>) + 'static, // on_complete ), ) { io_stream.input_stream().read_bytes_async( - chunk, + size.chunk, priority, Some(&cancellable.clone()), move |result| match result { Ok(bytes) => { - total += bytes.len(); - on_chunk(bytes.clone(), total); + size.total += bytes.len(); + on_chunk(bytes.clone(), size.total); - if let Some(limit) = limit { - if total > limit { - return on_complete(Err(Error::BytesTotal(total, limit))); + if let Some(limit) = size.limit { + if size.total > limit { + return on_complete(Err(Error::BytesTotal(size.total, limit))); } } if bytes.len() == 0 { - return on_complete(Ok((file_output_stream, total))); + return on_complete(Ok((file_output_stream, size.total))); } // Make sure **all bytes** sent to the destination // > A partial write is performed with the size of a message block, which is 16kB // > https://docs.openssl.org/3.0/man3/SSL_write/#notes file_output_stream.clone().write_all_async( - bytes.clone(), + bytes, priority, Some(&cancellable.clone()), - move |result| { - match result { - Ok(_) => { - // continue read.. - from_stream_async( - io_stream, - file_output_stream, - cancellable, - priority, - (chunk, limit, total), - (on_chunk, on_complete), - ); - } - Err((b, e)) => on_complete(Err(Error::OutputStream(b, e))), - } + move |result| match result { + Ok(_) => from_stream_async( + io_stream, + file_output_stream, + cancellable, + priority, + size, + (on_chunk, on_complete), + ), + Err((b, e)) => on_complete(Err(Error::OutputStream(b, e))), }, - ); + ) } Err(e) => on_complete(Err(Error::InputStream(e))), },