Skip to main content

Crate canton_codegen

Crate canton_codegen 

Source
Expand description

canton-codegen — generate typed Rust bindings from Daml packages.

This crate turns a DAR into idiomatic Rust: templates and records into structs, choices into typed exercise impls, interfaces into typed markers with views, with JSON and gRPC codecs on every generated type. The command-line front-end is canton-codegen-cli (dpm codegen-rust); most users drive codegen through that.

§Usage

lower_dar turns a .dar into the ir, and generate_crate turns that into the source of a self-contained bindings crate:

let dar = canton_lf::Dar::open("my-app-0.1.0.dar")?;
let (krate, skipped) = canton_codegen::lower_dar(&dar)?;
let source = canton_codegen::generate_crate(&krate)?;
for skip in &skipped {
    eprintln!("warning: skipped {}", skip);
}
std::fs::write("src/lib.rs", source)?;

§Architecture

A decoder-agnostic ir (intermediate representation) sits between decoding Daml-LF and emitting Rust:

DAR ──(canton-lf: decode)──▶ lower ──▶ ir ──(emit/map)──▶ Rust source

The generator and the type mapping consume the IR and never touch Daml-LF; lowering is the one step that reads the decoded LF AST (from canton-lf, which is held to the official daml-lf-archive reader by a conformance oracle). Every generator checks its output parses as valid Rust before returning it. The IR is public so a caller can emit something other than Rust from it, or post-process before emission; the emitter and type mapper are private (their signatures are proc-macro2 token streams, which would otherwise become part of this crate’s SemVer surface).

The human-readable specification of the type mapping lives in docs/daml-lf-type-mapping.md.

Re-exports§

pub use canton_lf;

Modules§

ir
A decoder-agnostic intermediate representation (IR) of Daml types.

Structs§

CodegenError
Emitting Rust from the ir failed.
ExternalPackages
Packages to reference rather than generate, keyed by package id or package name.
Options
What to generate and where. Build with Options::new, then the with_* methods.
Selection
Which of a DAR’s packages a crate emits.
SkippedType
A declaration that could not be lowered into the IR, and why.
Stats
A summary of a successful generation.

Enums§

GenerateError
Writing a bindings crate failed.
Runtime
How the generated crate depends on the canton-daml runtime.

Functions§

default_crate_name
Derive a crate name from a DAR path: its file stem with the trailing version dropped, sanitised to a valid Cargo package name (splice-amulet-0.1.14.dar → splice-amulet).
generate
Decode opts.dar, lower its whole closure, and write a bindings crate (Cargo.toml + src/lib.rs) into the output directory.
generate_crate
Generate a whole crate’s lib.rs from a lowered DAR: a pub mod tree (package → module → types) where every cross-module and cross-package reference resolves through its qualified path.
generate_data_type
Generate formatted Rust source for a named data type (record / variant / enum).
generate_interface
Generate formatted Rust source for an interface’s impls (its Contract / Interface identity and typed choice impls) on its marker type.
generate_module
Generate a complete module file: the use canton_daml as rt; preamble plus every data type and template, ready to write to a .rs file in a generated crate.
generate_record
Generate formatted Rust source for a single record data type.
generate_template
Generate formatted Rust source for a template: its payload struct plus the typed choice impls.
lower_dar
Lower a whole DAR (its main package and its full dependency closure) into a Crate of qualified modules, plus the list of types that could not be lowered (best-effort: see SkippedType).
lower_dar_selecting
The same, emitting only the packages a Selection names.
lower_dar_with
The same, with packages that are already published as their own crates referenced instead of re-emitted.
lower_packages_selecting
The same, from packages already decoded rather than from a DAR.