cobble-core 1.2.0

Library for managing, installing and launching Minecraft instances and more.
Documentation
use cobble_core::minecraft::{
    AssetInstallationUpdate, ClientInstallationUpdate, InstallationUpdate,
    LibraryInstallationUpdate, LogConfigInstallationUpdate,
};
use cobble_core::utils::DownloadProgress;
use cobble_core::Instance;
use tokio::join;
use tokio::sync::mpsc::Receiver;
use tracing_subscriber::FmtSubscriber;

pub const INSTANCE_JSON: &str = include_str!("instance.json");

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    FmtSubscriber::builder()
        .with_env_filter("info,cobble_core=debug")
        .init();

    // Parse JSON
    let mut instance = serde_json::from_str::<Instance>(INSTANCE_JSON)?;

    // Update channel
    let (tx, rx) = InstallationUpdate::channel(500);

    // Install
    join!(
        instance.full_installation(5, 5, true, tx),
        process_updates(rx)
    )
    .0?;

    assert!(instance.installed);

    Ok(())
}

async fn process_updates(mut rx: Receiver<InstallationUpdate>) {
    while let Some(update) = rx.recv().await {
        match update {
            InstallationUpdate::Library((n, p)) => match p {
                LibraryInstallationUpdate::Downloading(p) => print_progress(p),
                LibraryInstallationUpdate::Extracting => {
                    println!("{} extracting...", n);
                }
            },
            InstallationUpdate::Asset((n, p)) => match p {
                AssetInstallationUpdate::Downloading(p) => print_progress(p),
                AssetInstallationUpdate::Symlink => {
                    println!("{} symlink...", n);
                }
            },
            InstallationUpdate::LogConfig(p) => match p {
                LogConfigInstallationUpdate::Downloading(p) => print_progress(p),
            },
            InstallationUpdate::Client(p) => match p {
                ClientInstallationUpdate::Downloading(p) => print_progress(p),
            },
        }
    }
}

fn print_progress(p: DownloadProgress) {
    let name = p.file.file_name().map(|s| s.to_string_lossy()).unwrap();
    let percent = p.downloaded_bytes as f64 / p.total_bytes as f64;

    tracing::info!(
        "{} ({}/{}): {}% done",
        name,
        p.current_file + 1,
        p.total_files,
        (percent * 100.0) as u64
    );
}