Skip to main content

LanguageBackend

Trait LanguageBackend 

Source
pub trait LanguageBackend: Send + Sync {
    type Config: Serialize + Default + Clone + Send + Sync;

    // Required methods
    fn name(&self) -> &'static str;
    fn capabilities(&self) -> TargetCapabilities;
    fn files(
        &self,
        api: &Api,
        model: &BindingModel,
        out_dir: &Utf8Path,
        config: &Self::Config,
    ) -> Vec<OutputFile>;

    // Provided methods
    fn allows_unsupported(&self, config: &Self::Config) -> bool { ... }
    fn prefix<'a>(&self, config: &'a Self::Config) -> &'a str { ... }
    fn render_enum(
        &self,
        out: &mut String,
        e: &EnumBinding,
        config: &Self::Config,
    ) { ... }
    fn render_struct(
        &self,
        out: &mut String,
        module: &ModuleBinding,
        s: &StructBinding,
        config: &Self::Config,
    ) { ... }
    fn render_callback(
        &self,
        out: &mut String,
        module: &ModuleBinding,
        c: &CallbackBinding,
        config: &Self::Config,
    ) { ... }
    fn render_listener(
        &self,
        out: &mut String,
        module: &ModuleBinding,
        l: &ListenerBinding,
        config: &Self::Config,
    ) { ... }
    fn render_function(
        &self,
        out: &mut String,
        module: &ModuleBinding,
        f: &FnBinding,
        config: &Self::Config,
    ) { ... }
    fn emit_members(
        &self,
        out: &mut String,
        module: &ModuleBinding,
        config: &Self::Config,
    ) { ... }
}
Expand description

An idiomatic language backend over the shared BindingModel.

The single required method is files, which assembles the complete output set; pair it with impl_generator_via_backend! to wire the type into the Generator trait the CLI and orchestrator consume. That alone gives every backend the shared driver, the OutputFile model (rendering is pure; the driver does the I/O), an automatically-derived output_files, and one uniform Generator bridge.

Backends whose primary file is a straightforward per-module walk override the per-entity hooks (render_enum, render_struct, render_function, and optionally render_callback/render_listener) and call the provided emit_members from inside their module scoping — that is what removes the hand-rolled walk + call-shape dispatch each generator used to carry. Multi-pass backends (Ruby, .NET, Node, Android) instead build their own layout directly in files and leave the hooks at their no-op defaults.

Each hook renders into a String (matching how generators accumulate output) and is responsible for emitting its own doc comments — doc-comment shape varies too much between targets (docstrings, ///, KDoc, <summary>) to centralise here, but every backend shares emit_doc for the line/block flavours.

Required Associated Types§

Source

type Config: Serialize + Default + Clone + Send + Sync

Per-target, fully-typed configuration. Mirrors Generator::Config.

Required Methods§

Source

fn name(&self) -> &'static str

Stable short name ("swift", "python", …): the --target token.

Source

fn capabilities(&self) -> TargetCapabilities

The gated IDL features this backend implements (async functions, callbacks, listeners, iterators). Required — declaring capabilities explicitly is what lets the orchestrator fail loudly instead of a backend silently skipping a feature it never implemented.

Source

fn files( &self, api: &Api, model: &BindingModel, out_dir: &Utf8Path, config: &Self::Config, ) -> Vec<OutputFile>

Assemble the complete output set. The driver has already built model (via BindingModel::build with prefix) and passes the source api too, for the rare file (e.g. a .pyi stub) that needs the raw IR. Most backends render a primary source file by composing emit_members over model.modules, then append package manifests (package.json, pyproject.toml, go.mod, …) as additional OutputFiles.

Provided Methods§

Source

fn allows_unsupported(&self, config: &Self::Config) -> bool

Whether the bound config explicitly opted in to generating despite unsupported features (see Generator::allows_unsupported). Backends with partial capabilities override this to read their allow_unsupported config flag; full-capability backends keep the false default.

Source

fn prefix<'a>(&self, config: &'a Self::Config) -> &'a str

The C ABI symbol prefix the producer used. The driver builds the BindingModel with it so every emitted call targets the right exported symbol. Defaults to "weaveffi"; override when the config carries a configurable c_prefix.

Source

fn render_enum(&self, out: &mut String, e: &EnumBinding, config: &Self::Config)

Render one enum (its declaration and any helpers), including doc comments. Override when using emit_members.

Source

fn render_struct( &self, out: &mut String, module: &ModuleBinding, s: &StructBinding, config: &Self::Config, )

Render one struct: the wrapper type, its getters, lifecycle, and the optional builder. module is the owning module (for symbol paths). Override when using emit_members.

Source

fn render_callback( &self, out: &mut String, module: &ModuleBinding, c: &CallbackBinding, config: &Self::Config, )

Render a module-scope callback typedef. Default: no output (most idiomatic backends express callbacks inline at the async/listener call site).

Source

fn render_listener( &self, out: &mut String, module: &ModuleBinding, l: &ListenerBinding, config: &Self::Config, )

Render a listener’s register/unregister surface. Default: no output.

Source

fn render_function( &self, out: &mut String, module: &ModuleBinding, f: &FnBinding, config: &Self::Config, )

Render one function. Implementations match on f.shape (sync / async / iterator) and emit the idiomatic wrapper plus its doc comment. Override when using emit_members.

Source

fn emit_members( &self, out: &mut String, module: &ModuleBinding, config: &Self::Config, )

Emit every member of module in canonical order (enums → structs → callbacks → listeners → functions). Backends call this from within their own module scoping; overriding the per-entity hooks is what guarantees a single-pass backend cannot silently skip an entity kind.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§