use std::path::Path;
use anyhow::Context;
use async_compression::tokio::bufread::GzipDecoder;
use futures_util::TryStreamExt;
use tokio::io::{AsyncBufRead, AsyncReadExt, BufReader};
use tokio_tar::Archive;
use tracing::{info_span, Instrument};
#[tracing::instrument(err)]
pub async fn read_bundle(path: impl AsRef<Path> + std::fmt::Debug) -> anyhow::Result<Vec<u8>> {
let file = tokio::fs::File::open(path).await?;
let reader = BufReader::new(file);
load_bundle(reader).await
}
#[tracing::instrument(skip_all, err)]
pub async fn load_bundle(
reader: impl AsyncBufRead + Unpin + Send + Sync,
) -> anyhow::Result<Vec<u8>> {
let reader = GzipDecoder::new(reader);
let mut archive = Archive::new(reader);
let entries = archive.entries()?;
let mut entry = entries
.try_filter(|e| {
std::future::ready(
e.path()
.map(|p| p.as_os_str() == "/policy.wasm")
.unwrap_or(false),
)
})
.try_next()
.instrument(info_span!("find_bundle_entry"))
.await?
.context("could not find WASM policy in tar archive")?;
let mut buf = Vec::new();
entry
.read_to_end(&mut buf)
.instrument(info_span!("read_module"))
.await?;
Ok(buf)
}