remozipsy 0.0.1

zip implementation independent structs and helpers
Documentation
//! This example allows syncing a remote zip file to a local directory.
//! Execute via `cargo run --example=sync_remote_zip -- 'https://getsamplefiles.com/download/zip/sample-1.zip' ./downloaded`
//! contained files and extract the compressed data from a single file within

use clap::Parser;
use remozipsy::{
    model::Config,
    proto::{Progress, State},
    reqwest::ReqwestRemoteZip,
    tokio::TokioLocalStorage,
};
use std::{path::PathBuf, time::Duration};
use tracing::level_filters::LevelFilter;
use tracing_subscriber::EnvFilter;

/// Extract Single file from zip
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
    /// online url of the zip
    #[arg()]
    remote_url: String,

    /// directory to write to
    #[arg()]
    output_directory: PathBuf,
}

pub fn main() {
    let args = Args::parse();

    let mut filter = EnvFilter::default().add_directive(LevelFilter::INFO.into());

    let default_directives = ["h2=info"];
    for s in default_directives {
        filter = filter.add_directive(s.parse().unwrap());
    }
    match std::env::var("RUST_LOG") {
        Ok(env) => {
            for s in env.split(',') {
                match s.parse() {
                    Ok(d) => filter = filter.add_directive(d),
                    Err(err) => eprintln!("WARN ignoring log directive: `{s}`: {err}"),
                }
            }
        },
        Err(std::env::VarError::NotUnicode(os_string)) => {
            eprintln!("WARN ignoring log directives due to non-unicode data: {os_string:?}");
        },
        Err(std::env::VarError::NotPresent) => {},
    };

    tracing_subscriber::fmt().with_env_filter(filter).init();

    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();

    rt.block_on(tokio::fs::create_dir_all(&args.output_directory)).unwrap();

    let remote = ReqwestRemoteZip::new("remozipsy_demo".to_string(), args.remote_url).unwrap();
    let local = TokioLocalStorage::new(args.output_directory, Vec::new());

    let state = State::new(remote, local, Config::default());
    rt.block_on(sync(state));
}

async fn sync(mut state: State<ReqwestRemoteZip, TokioLocalStorage>) {
    let mut progress = Progress::Successful;
    while let Some((next_progress, next_state)) = state.progress().await {
        state = next_state;
        progress = next_progress;

        // Not important, just give the network some time
        tokio::time::sleep(Duration::from_millis(10)).await;

        // It's important to yield_now in a single threaded executor, as otherwise, the
        // background tasks, like actual downloading are NEVER triggered!
        tokio::task::yield_now().await;
    }

    println!("Sync finished with: {progress:?}");
}