#![deny(missing_docs)]
use std::{io::Read, str::FromStr};
use tectonic_errors::{anyhow::bail, atry, Result};
use tectonic_io_base::{digest, digest::DigestData, IoProvider, OpenResult};
use tectonic_status_base::StatusBackend;
pub mod cache;
pub mod dir;
pub mod itar;
pub mod zip;
pub trait Bundle: IoProvider {
fn get_digest(&mut self, status: &mut dyn StatusBackend) -> Result<DigestData> {
let digest_text = match self.input_open_name(digest::DIGEST_NAME, status) {
OpenResult::Ok(h) => {
let mut text = String::new();
h.take(64).read_to_string(&mut text)?;
text
}
OpenResult::NotAvailable => {
bail!("bundle does not provide needed SHA256SUM file");
}
OpenResult::Err(e) => {
return Err(e);
}
};
Ok(atry!(DigestData::from_str(&digest_text); ["corrupted SHA256 digest data"]))
}
fn all_files(&mut self, status: &mut dyn StatusBackend) -> Result<Vec<String>>;
}
impl<B: Bundle + ?Sized> Bundle for Box<B> {
fn get_digest(&mut self, status: &mut dyn StatusBackend) -> Result<DigestData> {
(**self).get_digest(status)
}
fn all_files(&mut self, status: &mut dyn StatusBackend) -> Result<Vec<String>> {
(**self).all_files(status)
}
}
pub fn get_fallback_bundle_url(format_version: u32) -> String {
if format_version < 32 {
"https://relay.fullyjustified.net/default_bundle.tar".to_owned()
} else {
format!(
"https://relay.fullyjustified.net/default_bundle_v{}.tar",
format_version
)
}
}
pub fn get_fallback_bundle(
format_version: u32,
only_cached: bool,
status: &mut dyn StatusBackend,
) -> Result<cache::CachingBundle<itar::IndexedTarBackend>> {
let url = get_fallback_bundle_url(format_version);
let mut cache = cache::Cache::get_user_default()?;
cache.open(&url, only_cached, status)
}