Skip to content

Runtime Compilation

Overview of Ferrocat's runtime-facing compile layers for normalized catalogs and locale-resolved artifacts.

Runtime Compilation

Parsing PO files is useful for tooling, but application runtimes usually need something smaller, faster, and easier to validate. Ferrocat exposes two compile layers above raw parsing so you can keep translator-friendly catalogs in the workflow while shipping application-ready artifacts.

This is one of the main handoff points to Palamedes: Ferrocat resolves catalog semantics and emits host-neutral artifacts, while Palamedes can package those artifacts through framework adapters, bundlers, and runtime loading code.

1. Compile one normalized catalog

Use NormalizedParsedCatalog::compile when you want a runtime-facing lookup structure with stable compiled keys and you are still working from one normalized catalog.

use ferrocat::{CompileCatalogOptions, ParseCatalogOptions, parse_catalog};

let parsed = parse_catalog(ParseCatalogOptions {
    content: "msgid \"Hello\"\nmsgstr \"Hallo\"\n",
    source_locale: "en",
    locale: Some("de"),
    ..ParseCatalogOptions::default()
})?;
let normalized = parsed.into_normalized_view()?;
let compiled = normalized.compile(&CompileCatalogOptions::default())?;

assert_eq!(compiled.len(), 1);
# Ok::<(), Box<dyn std::error::Error>>(())

Use this layer when you want:

  • stable derived runtime keys
  • typed runtime-oriented payloads
  • no locale fallback resolution yet

2. Compile a requested-locale artifact

Use compile_catalog_artifact when downstream tooling wants a fully resolved locale-specific runtime map, including fallback resolution and missing-message reporting.

use ferrocat::{
    CompileCatalogArtifactOptions, ParseCatalogOptions, compile_catalog_artifact, parse_catalog,
};

let source = parse_catalog(ParseCatalogOptions {
    content: "msgid \"Hello\"\nmsgstr \"Hello\"\n",
    source_locale: "en",
    locale: Some("en"),
    ..ParseCatalogOptions::default()
})?
.into_normalized_view()?;
let requested = parse_catalog(ParseCatalogOptions {
    content: "msgid \"Hello\"\nmsgstr \"Hallo\"\n",
    source_locale: "en",
    locale: Some("de"),
    ..ParseCatalogOptions::default()
})?
.into_normalized_view()?;

let artifact = compile_catalog_artifact(
    &[&requested, &source],
    &CompileCatalogArtifactOptions {
        requested_locale: "de",
        source_locale: "en",
        ..CompileCatalogArtifactOptions::default()
    },
)?;

assert_eq!(artifact.messages.len(), 1);
assert!(artifact.missing.is_empty());
# Ok::<(), Box<dyn std::error::Error>>(())

Use this layer when you need:

  • one requested-locale runtime map keyed by Ferrocat's compiled IDs
  • locale fallback resolution before host-specific code generation
  • explicit missing-message reporting for non-source locales
  • final ICU-string validation diagnostics
  • optional ICU source/translation compatibility diagnostics with icu_compatibility

strict_icu and icu_compatibility solve different problems. strict_icu turns invalid final ICU syntax into a hard compile error. icu_compatibility keeps compilation non-fatal and reports structural translation drift such as missing arguments, formatter changes, tag mismatches, select/plural branch changes, and discouraged formatter patterns.

For broader release QA, use audit_catalogs before compilation. Audit reports missing locales, missing or empty translations, stale target-only entries, visible fuzzy flags, obsolete entries, ICU syntax, ICU compatibility, and semantic metadata conflicts across a catalog set. Artifact compilation stays focused on producing one resolved runtime payload; audit answers whether the source and target catalogs are shippable.