ic-asset 0.29.0

Library for storing files in an asset canister.
Documentation
use crate::AssetSyncProgressRenderer;
use crate::asset::config::AssetConfig;
use crate::batch_upload::operations::BATCH_UPLOAD_API_VERSION;
use crate::batch_upload::plumbing::Mode::NormalDeploy;
use crate::batch_upload::{
    self,
    operations::AssetDeletionReason,
    plumbing::{AssetDescriptor, ChunkUploader, make_project_assets},
};
use crate::canister_api::methods::{
    api_version::api_version,
    batch::{commit_batch, create_batch},
    list::list_assets,
};
use crate::canister_api::types::batch_upload::v0;
use crate::error::CompatibilityError::DowngradeV1TOV0Failed;
use crate::error::UploadError::{
    self, ApiVersionQueryFailed, CommitBatchFailed, CreateBatchFailed, ListAssetsFailed,
};
use ic_utils::Canister;
use slog::{Logger, info};
use std::collections::HashMap;
use std::path::PathBuf;

/// Upload the specified files
pub async fn upload(
    canister: &Canister<'_>,
    files: HashMap<String, PathBuf>,
    logger: &Logger,
    progress: Option<&dyn AssetSyncProgressRenderer>,
) -> Result<(), UploadError> {
    let asset_descriptors: Vec<AssetDescriptor> = files
        .iter()
        .map(|x| AssetDescriptor {
            source: x.1.clone(),
            key: x.0.clone(),
            config: AssetConfig::default(),
        })
        .collect();

    let canister_assets = list_assets(canister).await.map_err(ListAssetsFailed)?;

    info!(logger, "Starting batch.");

    let batch_id = create_batch(canister).await.map_err(CreateBatchFailed)?;
    let canister_api_version = api_version(canister).await.map_err(ApiVersionQueryFailed)?;

    info!(logger, "Staging contents of new and changed assets:");

    let chunk_upload_target =
        ChunkUploader::new(canister.clone(), canister_api_version, batch_id.clone());

    let project_assets = make_project_assets(
        Some(&chunk_upload_target),
        asset_descriptors,
        &canister_assets,
        NormalDeploy,
        logger,
        progress,
    )
    .await?;

    let commit_batch_args = batch_upload::operations::assemble_commit_batch_arguments(
        &chunk_upload_target,
        project_assets,
        canister_assets,
        AssetDeletionReason::Incompatible,
        HashMap::new(),
        batch_id,
    )
    .await
    .map_err(UploadError::AssembleCommitBatchArgumentFailed)?;

    let canister_api_version = api_version(canister).await.map_err(ApiVersionQueryFailed)?;
    info!(logger, "Committing batch.");
    match canister_api_version {
        0 => {
            let commit_batch_args_v0 = v0::CommitBatchArguments::try_from(commit_batch_args)
                .map_err(DowngradeV1TOV0Failed)?;
            commit_batch(canister, commit_batch_args_v0).await
        }
        BATCH_UPLOAD_API_VERSION.. => commit_batch(canister, commit_batch_args).await,
    }
    .map_err(CommitBatchFailed)
}