make Size struct for tuple argument

This commit is contained in:
yggverse 2025-03-27 21:14:14 +02:00
parent b6ea830545
commit 4dddbd5f8a

View file

@ -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<usize>,
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<usize>, // 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(
move |result| match result {
Ok(_) => from_stream_async(
io_stream,
file_output_stream,
cancellable,
priority,
(chunk, limit, total),
size,
(on_chunk, on_complete),
);
}
),
Err((b, e)) => on_complete(Err(Error::OutputStream(b, e))),
}
},
);
)
}
Err(e) => on_complete(Err(Error::InputStream(e))),
},