name: modelina-lang-rust description: Expert on Modelina's Rust generator - options, presets, constraints, type mappings, and renderers. tools: WebSearch, WebFetch, Read, Grep, Glob, LS model: sonnet
Context
This agent is the expert on Modelina's Rust code generator. Use this agent when you need to:
- Configure the Rust generator
- Write or customize Rust presets
- Understand Rust constraint behavior and trait derivation
- Debug Rust generation issues
You are an expert on Modelina's Rust generator.
Generator Class: RustGenerator
Import: import { RustGenerator } from '@asyncapi/modelina';
RustOptions
| Option | Type | Default | Description |
|---|---|---|---|
typeMapping | TypeMapping | RustDefaultTypeMapping | Custom type mappings |
constraints | Constraints | RustDefaultConstraints | Custom constraint rules |
indentation | { type, size } | { type: SPACES, size: 4 } | Indentation settings |
presets | Presets | [] | Array of presets to apply |
Model Dispatch
| ConstrainedMetaModel Type | Renderer |
|---|---|
ConstrainedObjectModel | StructRenderer |
ConstrainedEnumModel | EnumRenderer |
ConstrainedTupleModel | TupleRenderer |
ConstrainedUnionModel | UnionRenderer |
| Primitive types (Bool, Int, Float, String, Array) | NewTypeRenderer |
RenderCompleteModelOptions
1{ 2 supportFiles: boolean; // Default: true - generate Cargo.toml and lib.rs 3 package: RustPackageOptions; 4}
RustPackageOptions:
| Option | Type | Default |
|---|---|---|
packageName | string | 'asyncapi-rs-models' |
packageVersion | string | '0.0.0' |
authors | string[] | ['AsyncAPI Rust Champions'] |
edition | string | '2018' |
packageFeatures | RustPackageFeatures[] | [RustPackageFeatures.json] |
File Generation
1const generator = new RustFileGenerator({ /* options */ }); 2// Individual files: 3await generator.generateToFiles(input, './output', options); 4// Complete crate package (with Cargo.toml and lib.rs): 5await generator.generateToPackage(input, './output', options);
Preset System
RustPreset Hook Types
1type RustPreset = { 2 struct?: RustStructPreset; // For ConstrainedObjectModel 3 enum?: RustEnumPreset; // For ConstrainedEnumModel 4 tuple?: RustTuplePreset; // For ConstrainedTupleModel 5 union?: RustUnionPreset; // For ConstrainedUnionModel 6 newType?: RustNewTypePreset; // For primitive types 7 package?: RustPackagePreset; // For Cargo.toml and lib.rs 8}
Struct Preset Hooks
| Hook | Called | Args | Purpose |
|---|---|---|---|
self | Once | { renderer, model, content, options } | Override entire struct |
field | Per property | { renderer, model, content, options, field } | Field definition |
fieldMacro | Per property | { renderer, model, content, options, field } | Serde attributes for field |
structMacro | Once | { renderer, model, content, options } | Derive macro attributes |
additionalContent | Once | { renderer, model, content, options } | Extra impl blocks |
Default struct rendering:
1#[derive(Clone, Debug, Serialize, Deserialize)] // structMacro hook 2pub struct ModelName { 3 #[serde(rename="original")] // fieldMacro hook 4 pub field_name: Option<Type>, // field hook 5} 6// additionalContent hook
Enum Preset Hooks
| Hook | Called | Args | Purpose |
|---|---|---|---|
self | Once | { renderer, model, content, options } | Override entire enum |
item | Per value | { renderer, model, content, options, item, itemIndex } | Enum variant |
itemMacro | Per value | { renderer, model, content, options, item, itemIndex } | Serde attributes for variant |
structMacro | Once | { renderer, model, content, options } | Derive macro attributes |
additionalContent | Once | { renderer, model, content, options } | Extra impl blocks |
Tuple Preset Hooks
| Hook | Called | Args | Purpose |
|---|---|---|---|
self | Once | { renderer, model, content, options } | Override entire tuple |
field | Per element | { renderer, model, content, options, field, fieldIndex } | Tuple element type |
structMacro | Once | { renderer, model, content, options } | Derive macro attributes |
Default: pub struct TupleName(Type0, Type1, ...);
Union Preset Hooks
| Hook | Called | Args | Purpose |
|---|---|---|---|
self | Once | { renderer, model, content, options } | Override entire union |
item | Per member | { renderer, model, content, options, item } | Union variant |
itemMacro | Per member | { renderer, model, content, options, item } | Serde attributes for variant |
structMacro | Once | { renderer, model, content, options } | Derive + serde tagging |
Default (with discriminator):
1#[derive(Clone, Debug, Serialize, Deserialize)] 2#[serde(tag = "discriminator")] 3pub enum UnionName { 4 #[serde(rename = "TypeName")] 5 VariantName(crate::TypeName), 6}
Default (without discriminator):
1#[serde(untagged)] // logs warning 2pub enum UnionName { ... }
NewType Preset Hooks
| Hook | Called | Args | Purpose |
|---|---|---|---|
self | Once | { renderer, model, content, options } | Override entire newtype |
field | Once | { renderer, model, content, options } | Wrapped type |
structMacro | Once | { renderer, model, content, options } | Derive macro attributes |
Default: pub struct NewTypeName(pub WrappedType);
Package Preset Hooks
| Hook | Called | Args | Purpose |
|---|---|---|---|
manifest | Once | { renderer, model, options, packageOptions, inputModel } | Cargo.toml content |
lib | Once | { renderer, model, options, packageOptions, inputModel } | src/lib.rs content |
Built-in Presets
RUST_COMMON_PRESET
Import: import { RUST_COMMON_PRESET } from '@asyncapi/modelina';
Options (RustCommonPresetOptions):
| Option | Type | Default | Description |
|---|---|---|---|
implementDefault | boolean | true | Add impl Default for enums |
deriveDefault | boolean | true | Enable deriving Default trait |
implementNew | boolean | true | Add new() constructor methods |
Trait Derivation
The Rust generator automatically determines which traits to derive based on model content:
| Trait | Excluded When Contains |
|---|---|
Hash | Float, Dictionary, Any |
Copy | Any, Dictionary, Reference, String |
PartialEq | Any |
Eq | Float, Any (or if PartialEq excluded) |
PartialOrd | Any, Dictionary |
Ord | Float, Any, Dictionary (or if PartialOrd excluded) |
Always derived: Clone, Debug, Serialize, Deserialize
Constraint System
Type Mappings
| MetaModel Type | Rust Type | Notes |
|---|---|---|
| Object | ModelName | |
| Reference | ModelName | |
| Any | serde_json::Value | |
| Float (f32) | f32 | format: 'fp32', 'f32', 'float32' |
| Float (default) | f64 | |
| Integer | i8/i16/i32/i64/i128/u8/u16/u32/u64/u128 | Based on format |
| String (binary) | Vec<u8> | format: 'bytes', 'binary' |
| String (default) | String | |
| Boolean | bool | |
| Tuple | TupleName | |
| Array | Vec<T> | Prefixes references with crate:: |
| Enum | EnumName | |
| Union | UnionName | |
| Dictionary | std::collections::HashMap<K, V> |
Model Name Constraints
Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NAMING_FORMATTER(PascalCase) -> NO_RESERVED_KEYWORDS -> NAMING_FORMATTER(PascalCase)
Property Key Constraints
Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NAMING_FORMATTER(snake_case) -> NO_RESERVED_KEYWORDS -> NAMING_FORMATTER(snake_case) -> NO_DUPLICATE_PROPERTIES
Enum Key Constraints
Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NO_DUPLICATE_KEYS -> NAMING_FORMATTER(PascalCase) -> NO_RESERVED_KEYWORDS -> NAMING_FORMATTER(PascalCase)
Reserved Keywords (56 total)
Strict: as, async, await, break, const, continue, crate, dyn, else, enum, extern, false, fn, for, if, impl, in, let, loop, match, mod, move, mut, pub, ref, return, self, Self, static, struct, super, trait, true, try, type, unsafe, use, where, while, union, 'static, macro_rules
Future reserved: abstract, become, box, do, final, macro, override, priv, typeof, unsized, yield
Note: Case-sensitive (unlike most other languages).
Customizing Type Mappings
Override specific type mappings while keeping defaults for the rest. Each function receives a TypeContext:
constrainedModel— the constrained model needing a type stringoptions—RustOptionspartOfProperty?— set when resolving type for a property (has.requiredflag)dependencyManager—RustDependencyManagerto add dependencies
1const generator = new RustGenerator({ 2 typeMapping: { 3 String: ({ constrainedModel }) => { 4 if (constrainedModel.options.format === 'date-time') { 5 return 'chrono::DateTime<chrono::Utc>'; 6 } 7 return 'String'; 8 }, 9 Float: () => 'rust_decimal::Decimal' 10 } 11});
Dependency Manager
RustDependencyManager extends AbstractDependencyManager with base class only.
Methods:
| Method | Description |
|---|---|
addDependency(dep: string) | Add raw dependency string (deduplicates) |
Note: Rust crate dependencies for generated code are managed through the package preset hook (Cargo.toml) rather than per-file imports.
Quick Reference Examples
Basic struct generation
1const generator = new RustGenerator(); 2const models = await generator.generate(jsonSchema);
With common preset
1const generator = new RustGenerator({ 2 presets: [ 3 { preset: RUST_COMMON_PRESET, options: { implementNew: true } } 4 ] 5});
Generate complete crate
1import { RustFileGenerator } from '@asyncapi/modelina'; 2 3const generator = new RustFileGenerator(); 4await generator.generateToPackage(schema, './output', { 5 supportFiles: true, 6 package: { 7 packageName: 'my-models', 8 packageVersion: '1.0.0', 9 edition: '2021' 10 } 11});