remozipsy 0.0.1

zip implementation independent structs and helpers
Documentation
use std::sync::Mutex;

use crate::proto::sync::UnzipResult;
use tokio::task::JoinHandle;

use super::{DownloadResult, FileSystem, RemoteZip};

#[rustversion::since(1.87)]
#[inline]
#[expect(clippy::type_complexity)]
pub(crate) fn process_handles<R, F>(
    download_handles: &mut Vec<JoinHandle<DownloadResult<R, F>>>,
    unzip_handles: &Mutex<Vec<JoinHandle<UnzipResult<R, F>>>>,
) -> (
    Vec<JoinHandle<DownloadResult<R, F>>>,
    Option<Vec<JoinHandle<UnzipResult<R, F>>>>,
)
where
    R: RemoteZip,
    F: FileSystem,
{
    // extract downloads finished in meantime, downloads return now value, as they
    // trigger unzips during runtime
    let finished_handle_iter = download_handles.extract_if(.., |handle| handle.is_finished());

    // extract unzips finished in meantime
    let finished_unzip_handles: Option<Vec<_>> = unzip_handles
        .try_lock()
        .map(|mut guard| guard.extract_if(.., |handle| handle.is_finished()).collect())
        .ok();

    (finished_handle_iter, finished_unzip_handles)
}

#[rustversion::before(1.87)]
#[inline]
#[expect(clippy::type_complexity)]
pub(crate) fn process_handles<R, F>(
    download_handles: &mut Vec<JoinHandle<DownloadResult<R, F>>>,
    unzip_handles: &Mutex<Vec<JoinHandle<UnzipResult<R, F>>>>,
) -> (
    Vec<JoinHandle<DownloadResult<R, F>>>,
    Option<Vec<JoinHandle<UnzipResult<R, F>>>>,
)
where
    R: RemoteZip,
    F: FileSystem,
{
    // extract downloads finished in meantime, downloads return now value, as they
    // trigger unzips during runtime
    let mut finished_download_handles = Vec::new();
    let mut i = 0;
    while i < download_handles.len() {
        if download_handles[i].is_finished() {
            finished_download_handles.push(download_handles.remove(i));
        } else {
            i += 1;
        }
    }

    // extract unzips finished in meantime
    let finished_unzip_handles: Option<Vec<_>> = unzip_handles
        .try_lock()
        .map(|mut guard| {
            let mut finished = Vec::new();
            let mut i = 0;
            while i < guard.len() {
                if guard[i].is_finished() {
                    finished.push(guard.remove(i));
                } else {
                    i += 1;
                }
            }
            finished
        })
        .ok();

    (finished_download_handles, finished_unzip_handles)
}