Skip to main content

create

Function create 

Source
pub fn create(
    input: PackCreationInput<'_>,
) -> Result<PackCreationOutcome, PackCreationError>
Expand description

Runs one representative Typst request over the supplied inputs and issues the Pack it selected, or reports the packages it needed and was not given.

Compiler observations select package and font requirements; project files come from the Project Snapshot alone. Creation fails rather than issuing an incomplete Pack when the representative request does not compile.

A request that read a package no supplied tree covers returns PackCreationOutcome::MissingPackageSpecifications instead: resolve those specifications, add their trees to the Package Catalog, and invoke creation again. Because a failed import ends module evaluation, one round reports what that round reached, and a project needing several packages completes over repeated invocation. A specification the caller cannot resolve is added to PackageReadFailures, which fails the next round’s Dependency Discovery at the import that needed it.

Creation borrows validated bytes and has nothing to re-read. A Pack represents the exact values its source adapters read, without guaranteeing that values from mutable sources all coexisted at one instant.

§Resuming until every package is supplied

The caller owns the retry loop, so any source can back it — a registry, a local directory, an object store, or a test fixture.

use typst::syntax::package::PackageSpec;
use typst_pack::{
    DiscoverySpecification, FontCatalog, Pack, PackCreationInput, PackCreationOutcome,
    PackageCatalog, PackageDisposition, PackageReadFailures, PackageTree, ProjectSnapshot,
    create,
};

fn assemble(
    project: &ProjectSnapshot,
    fonts: &FontCatalog,
    discovery: &DiscoverySpecification,
    mut read_tree: impl FnMut(&PackageSpec) -> Result<PackageTree, Box<dyn std::error::Error>>,
) -> Result<Pack, Box<dyn std::error::Error>> {
    let mut packages = PackageCatalog::new();
    let package_failures = PackageReadFailures::new();
    loop {
        let outcome = create(PackCreationInput {
            project,
            packages: &packages,
            fonts,
            package_failures: &package_failures,
            discovery,
            metadata: None,
        })?;
        match outcome {
            PackCreationOutcome::Created { pack, .. } => return Ok(pack),
            PackCreationOutcome::MissingPackageSpecifications(missing) => {
                for spec in missing {
                    let tree = read_tree(&spec)?;
                    packages.insert(spec, tree, PackageDisposition::Embedded)?;
                }
            }
        }
    }
}