alef_core/config/languages.rs
1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::path::PathBuf;
4
5use super::extras::Language;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct PythonConfig {
9 pub module_name: Option<String>,
10 pub async_runtime: Option<String>,
11 pub stubs: Option<StubsConfig>,
12 /// PyPI package name (e.g. `"html-to-markdown"`). Used as the `[project] name` in
13 /// `pyproject.toml` and to derive the `python-packages` list for maturin.
14 /// Defaults to the crate name.
15 #[serde(default)]
16 pub pip_name: Option<String>,
17 /// Per-language feature override. When set, these features are used instead of
18 /// `[crate] features` for this language's binding crate.
19 #[serde(default)]
20 pub features: Option<Vec<String>>,
21 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
22 /// When set, this takes priority over the IR type-level serde_rename_all.
23 #[serde(default)]
24 pub serde_rename_all: Option<String>,
25 /// Map of type name -> PyCapsule name for raw pointer wrapping.
26 /// When a function returns one of these types, alef generates PyCapsule_New instead of Arc wrapping.
27 // TODO: Wire into gen_bindings.rs to emit PyCapsule_New / PyCapsule_GetPointer at call sites.
28 #[serde(default)]
29 pub capsule_types: HashMap<String, String>,
30 /// When true, wrap blocking function bodies in py.allow_threads() to release the GIL.
31 // TODO: Wire into gen_bindings.rs to emit py.allow_threads(|| { ... }) for non-async functions.
32 #[serde(default)]
33 pub release_gil: bool,
34 /// Functions to exclude from Python binding generation.
35 #[serde(default)]
36 pub exclude_functions: Vec<String>,
37 /// Types to exclude from Python binding generation.
38 #[serde(default)]
39 pub exclude_types: Vec<String>,
40 /// Additional Cargo dependencies for this language's binding crate only.
41 #[serde(default)]
42 pub extra_dependencies: HashMap<String, toml::Value>,
43 /// Override the scaffold output directory for this language's Cargo.toml and package files.
44 #[serde(default)]
45 pub scaffold_output: Option<PathBuf>,
46 /// Per-field name remapping for this language. Key is `TypeName.field_name` (e.g.
47 /// `"LayoutDetection.class"`), value is the desired binding field name. Applied after
48 /// automatic keyword escaping, so an explicit entry takes priority.
49 #[serde(default)]
50 pub rename_fields: HashMap<String, String>,
51 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
52 /// commands across all pipelines (lint, test, build, etc.).
53 /// E.g., `run_wrapper = "uv run --no-sync"` turns `ruff format packages/python` into
54 /// `uv run --no-sync ruff format packages/python`.
55 #[serde(default)]
56 pub run_wrapper: Option<String>,
57 /// Extra paths to append to default lint commands (format, check, typecheck).
58 /// Space-separated paths are appended to the command.
59 #[serde(default)]
60 pub extra_lint_paths: Vec<String>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct StubsConfig {
65 pub output: PathBuf,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct NodeConfig {
70 pub package_name: Option<String>,
71 /// Per-language feature override. When set, these features are used instead of
72 /// `[crate] features` for this language's binding crate.
73 #[serde(default)]
74 pub features: Option<Vec<String>>,
75 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
76 /// When set, this takes priority over the IR type-level serde_rename_all.
77 #[serde(default)]
78 pub serde_rename_all: Option<String>,
79 /// Prefix for generated type names (e.g. "Js" produces `JsConversionOptions`).
80 /// Defaults to `"Js"`.
81 #[serde(default)]
82 pub type_prefix: Option<String>,
83 /// Functions to exclude from Node binding generation.
84 #[serde(default)]
85 pub exclude_functions: Vec<String>,
86 /// Types to exclude from Node binding generation.
87 #[serde(default)]
88 pub exclude_types: Vec<String>,
89 /// Additional Cargo dependencies for this language's binding crate only.
90 #[serde(default)]
91 pub extra_dependencies: HashMap<String, toml::Value>,
92 /// Override the scaffold output directory for this language's Cargo.toml and package files.
93 #[serde(default)]
94 pub scaffold_output: Option<PathBuf>,
95 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
96 /// desired binding field name. Applied after automatic keyword escaping.
97 #[serde(default)]
98 pub rename_fields: HashMap<String, String>,
99 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
100 /// commands across all pipelines (lint, test, build, etc.).
101 #[serde(default)]
102 pub run_wrapper: Option<String>,
103 /// Extra paths to append to default lint commands (format, check, typecheck).
104 #[serde(default)]
105 pub extra_lint_paths: Vec<String>,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct RubyConfig {
110 pub gem_name: Option<String>,
111 pub stubs: Option<StubsConfig>,
112 /// Per-language feature override. When set, these features are used instead of
113 /// `[crate] features` for this language's binding crate.
114 #[serde(default)]
115 pub features: Option<Vec<String>>,
116 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
117 /// When set, this takes priority over the IR type-level serde_rename_all.
118 #[serde(default)]
119 pub serde_rename_all: Option<String>,
120 /// Functions to exclude from Ruby binding generation.
121 #[serde(default)]
122 pub exclude_functions: Vec<String>,
123 /// Types to exclude from Ruby binding generation.
124 #[serde(default)]
125 pub exclude_types: Vec<String>,
126 /// Additional Cargo dependencies for this language's binding crate only.
127 #[serde(default)]
128 pub extra_dependencies: HashMap<String, toml::Value>,
129 /// Override the scaffold output directory for this language's Cargo.toml and package files.
130 #[serde(default)]
131 pub scaffold_output: Option<PathBuf>,
132 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
133 /// desired binding field name. Applied after automatic keyword escaping.
134 #[serde(default)]
135 pub rename_fields: HashMap<String, String>,
136 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
137 /// commands across all pipelines (lint, test, build, etc.).
138 #[serde(default)]
139 pub run_wrapper: Option<String>,
140 /// Extra paths to append to default lint commands (format, check, typecheck).
141 #[serde(default)]
142 pub extra_lint_paths: Vec<String>,
143}
144
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct PhpConfig {
147 pub extension_name: Option<String>,
148 /// Cargo crate name for the PHP binding (e.g. `"ts-pack-core-php"`).
149 /// Used to derive the shared library filename in the e2e test runner.
150 /// When absent, the lib name is derived from `extension_name` by appending `_php`.
151 #[serde(default)]
152 pub cargo_crate_name: Option<String>,
153 /// Override the PHP namespace used for class registration and PSR-4 autoloading.
154 ///
155 /// When set, this value is used verbatim as the PHP namespace (e.g. `"HtmlToMarkdown"`).
156 /// When absent, the namespace is derived from `extension_name` by splitting on `_` and
157 /// converting each segment to PascalCase (e.g. `html_to_markdown` → `Html\To\Markdown`).
158 #[serde(default)]
159 pub namespace: Option<String>,
160 /// Feature gate for ext-php-rs (default: "extension-module").
161 /// All generated code is wrapped in `#[cfg(feature = "...")]`.
162 #[serde(default)]
163 pub feature_gate: Option<String>,
164 /// Output directory for generated PHP facade / stubs (e.g., `packages/php/src/`).
165 #[serde(default)]
166 pub stubs: Option<StubsConfig>,
167 #[serde(default)]
168 pub features: Option<Vec<String>>,
169 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
170 /// When set, this takes priority over the IR type-level serde_rename_all.
171 #[serde(default)]
172 pub serde_rename_all: Option<String>,
173 /// Functions to exclude from PHP binding generation.
174 #[serde(default)]
175 pub exclude_functions: Vec<String>,
176 /// Types to exclude from PHP binding generation.
177 #[serde(default)]
178 pub exclude_types: Vec<String>,
179 /// Additional Cargo dependencies for this language's binding crate only.
180 #[serde(default)]
181 pub extra_dependencies: HashMap<String, toml::Value>,
182 /// Override the scaffold output directory for this language's Cargo.toml and package files.
183 #[serde(default)]
184 pub scaffold_output: Option<PathBuf>,
185 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
186 /// desired binding field name. Applied after automatic keyword escaping.
187 #[serde(default)]
188 pub rename_fields: HashMap<String, String>,
189 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
190 /// commands across all pipelines (lint, test, build, etc.).
191 #[serde(default)]
192 pub run_wrapper: Option<String>,
193 /// Extra paths to append to default lint commands (format, check, typecheck).
194 #[serde(default)]
195 pub extra_lint_paths: Vec<String>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct ElixirConfig {
200 pub app_name: Option<String>,
201 #[serde(default)]
202 pub features: Option<Vec<String>>,
203 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
204 /// When set, this takes priority over the IR type-level serde_rename_all.
205 #[serde(default)]
206 pub serde_rename_all: Option<String>,
207 /// Functions to exclude from Elixir NIF generation.
208 #[serde(default)]
209 pub exclude_functions: Vec<String>,
210 /// Types to exclude from Elixir NIF generation.
211 #[serde(default)]
212 pub exclude_types: Vec<String>,
213 /// Additional Cargo dependencies for this language's binding crate only.
214 #[serde(default)]
215 pub extra_dependencies: HashMap<String, toml::Value>,
216 /// Override the scaffold output directory for this language's Cargo.toml and package files.
217 #[serde(default)]
218 pub scaffold_output: Option<PathBuf>,
219 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
220 /// desired binding field name. Applied after automatic keyword escaping.
221 #[serde(default)]
222 pub rename_fields: HashMap<String, String>,
223 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
224 /// commands across all pipelines (lint, test, build, etc.).
225 #[serde(default)]
226 pub run_wrapper: Option<String>,
227 /// Extra paths to append to default lint commands (format, check, typecheck).
228 #[serde(default)]
229 pub extra_lint_paths: Vec<String>,
230 /// Functions that should be scheduled on the dirty CPU scheduler.
231 /// HTML parsing and other CPU-intensive NIFs should be listed here to avoid
232 /// blocking BEAM scheduler threads.
233 #[serde(default)]
234 pub cpu_bound_functions: Vec<String>,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct WasmConfig {
239 #[serde(default)]
240 pub exclude_functions: Vec<String>,
241 #[serde(default)]
242 pub exclude_types: Vec<String>,
243 #[serde(default)]
244 pub type_overrides: HashMap<String, String>,
245 #[serde(default)]
246 pub features: Option<Vec<String>>,
247 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
248 /// When set, this takes priority over the IR type-level serde_rename_all.
249 #[serde(default)]
250 pub serde_rename_all: Option<String>,
251 /// Prefix for generated type names (e.g. "Wasm" produces `WasmConversionOptions`).
252 /// Defaults to `"Wasm"`.
253 #[serde(default)]
254 pub type_prefix: Option<String>,
255 /// Functions to exclude from the public TypeScript re-export (index.ts) while still
256 /// generating the Rust binding. Use this when a custom module provides a wrapper.
257 #[serde(default)]
258 pub exclude_reexports: Vec<String>,
259 /// Wide-character C functions to shim for WASM external scanner interop.
260 #[serde(default)]
261 pub env_shims: Vec<String>,
262 /// Additional Cargo dependencies for the WASM binding crate only.
263 #[serde(default)]
264 pub extra_dependencies: HashMap<String, toml::Value>,
265 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
266 /// desired binding field name. Applied after automatic keyword escaping.
267 #[serde(default)]
268 pub rename_fields: HashMap<String, String>,
269 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
270 /// commands across all pipelines (lint, test, build, etc.).
271 #[serde(default)]
272 pub run_wrapper: Option<String>,
273 /// Extra paths to append to default lint commands (format, check, typecheck).
274 #[serde(default)]
275 pub extra_lint_paths: Vec<String>,
276 /// Override the core Cargo dependency name and path for the WASM binding crate.
277 /// When set, the binding `Cargo.toml` depends on this crate (resolved as
278 /// `../<override>`) instead of the umbrella `[crate.name]`. Use this to point
279 /// the WASM binding at a wasm-safe sub-crate while other languages keep the
280 /// facade. Defaults to unset.
281 #[serde(default)]
282 pub core_crate_override: Option<String>,
283 /// Keys to subtract from the merged `extra_dependencies` set for this
284 /// language only. Useful when `[crate.extra_dependencies]` lists sibling
285 /// crates that the WASM target cannot link.
286 #[serde(default)]
287 pub exclude_extra_dependencies: Vec<String>,
288 /// Hand-written Rust modules to declare in the generated lib.rs with `pub mod <name>;`
289 /// and re-export with `pub use <name>::*;`. Separate from `[custom_modules].wasm` which
290 /// only adds TypeScript `export *` re-exports. Use this for Rust-side dispatch/glue modules.
291 #[serde(default)]
292 pub custom_rust_modules: Vec<String>,
293 /// Per-type field exclusions for the generated From impls and binding struct.
294 /// Key is the type name (e.g. "ServerConfig"), value is a list of field names to skip.
295 /// Use when source fields are gated behind `#[cfg(not(target_arch = "wasm32"))]` and
296 /// therefore don't exist in the wasm32 compilation environment.
297 #[serde(default)]
298 pub exclude_fields: HashMap<String, Vec<String>>,
299 /// Source crate names whose types are re-exported by the `core_crate_override`
300 /// crate. References to `<original_crate>::TypeName` in generated code are
301 /// rewritten to `<override_crate>::TypeName`. Only meaningful when
302 /// `core_crate_override` is set.
303 /// Example: with `core_crate_override = "mylib-http"`, setting
304 /// `source_crate_remaps = ["mylib-core", "mylib"]` rewrites
305 /// `mylib_core::Method` and `mylib::Method` references to
306 /// `mylib_http::Method` (assumes `mylib-http` re-exports them via
307 /// `pub use mylib_core::*`).
308 #[serde(default)]
309 pub source_crate_remaps: Vec<String>,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct FfiConfig {
314 pub prefix: Option<String>,
315 #[serde(default = "default_error_style")]
316 pub error_style: String,
317 pub header_name: Option<String>,
318 /// Native library name for Go cgo/Java Panama/C# P/Invoke (e.g., "ts_pack_ffi").
319 /// Defaults to `{prefix}_ffi`.
320 #[serde(default)]
321 pub lib_name: Option<String>,
322 /// If true, generate visitor/callback FFI support.
323 #[serde(default)]
324 pub visitor_callbacks: bool,
325 #[serde(default)]
326 pub features: Option<Vec<String>>,
327 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
328 /// When set, this takes priority over the IR type-level serde_rename_all.
329 #[serde(default)]
330 pub serde_rename_all: Option<String>,
331 /// Functions to exclude from FFI binding generation.
332 #[serde(default)]
333 pub exclude_functions: Vec<String>,
334 /// Types to exclude from FFI binding generation.
335 #[serde(default)]
336 pub exclude_types: Vec<String>,
337 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
338 /// desired binding field name. Applied after automatic keyword escaping.
339 #[serde(default)]
340 pub rename_fields: HashMap<String, String>,
341 /// Rust expression used to construct an error value of this crate's
342 /// `error_type` from a runtime `String` message inside generated FFI
343 /// trait-bridge plugin shims (`plugin_impl_initialize`, `plugin_impl_shutdown`).
344 ///
345 /// The expression has access to a local variable `msg: String` containing
346 /// the underlying error message and is interpolated verbatim. Example
347 /// values:
348 ///
349 /// ```toml
350 /// # downstream whose error type has a struct variant with two fields:
351 /// plugin_error_constructor = """
352 /// kreuzberg::KreuzbergError::Plugin { message: msg, plugin_name: String::new() }
353 /// """
354 ///
355 /// # downstream whose error type implements `From<String>`:
356 /// plugin_error_constructor = "MyError::from(msg)"
357 /// ```
358 ///
359 /// Defaults to `None`. When unset, the plugin shim still emits — backends
360 /// fall back to a `format!("{}: {}", prefix, msg)`-style construction via
361 /// the configured `error_constructor`. Downstreams that don't expose
362 /// trait-bridged plugins can ignore this knob entirely.
363 #[serde(default)]
364 pub plugin_error_constructor: Option<String>,
365}
366
367fn default_error_style() -> String {
368 "last_error".to_string()
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
372pub struct GoConfig {
373 pub module: Option<String>,
374 /// Override the Go package name (default: derived from module path)
375 pub package_name: Option<String>,
376 #[serde(default)]
377 pub features: Option<Vec<String>>,
378 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
379 /// When set, this takes priority over the IR type-level serde_rename_all.
380 #[serde(default)]
381 pub serde_rename_all: Option<String>,
382 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
383 /// desired binding field name. Applied after automatic keyword escaping.
384 #[serde(default)]
385 pub rename_fields: HashMap<String, String>,
386 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
387 /// commands across all pipelines (lint, test, build, etc.).
388 #[serde(default)]
389 pub run_wrapper: Option<String>,
390 /// Extra paths to append to default lint commands (format, check, typecheck).
391 #[serde(default)]
392 pub extra_lint_paths: Vec<String>,
393}
394
395#[derive(Debug, Clone, Serialize, Deserialize)]
396pub struct JavaConfig {
397 pub package: Option<String>,
398 #[serde(default = "default_java_ffi_style")]
399 pub ffi_style: String,
400 #[serde(default)]
401 pub features: Option<Vec<String>>,
402 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
403 /// When set, this takes priority over the IR type-level serde_rename_all.
404 #[serde(default)]
405 pub serde_rename_all: Option<String>,
406 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
407 /// desired binding field name. Applied after automatic keyword escaping.
408 #[serde(default)]
409 pub rename_fields: HashMap<String, String>,
410 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
411 /// commands across all pipelines (lint, test, build, etc.).
412 #[serde(default)]
413 pub run_wrapper: Option<String>,
414 /// Extra paths to append to default lint commands (format, check, typecheck).
415 /// Ignored when project_file is set.
416 #[serde(default)]
417 pub extra_lint_paths: Vec<String>,
418 /// Project file for Maven/Gradle (e.g., "pom.xml", "build.gradle"). When set, default
419 /// lint/build/test commands target this file instead of the output directory.
420 #[serde(default)]
421 pub project_file: Option<String>,
422}
423
424fn default_java_ffi_style() -> String {
425 "panama".to_string()
426}
427
428/// Target platform for Kotlin code generation.
429///
430/// - `"jvm"` (default): emits source consuming the Java/Panama FFM facade.
431/// - `"native"`: emits Kotlin/Native source consuming the cbindgen C FFI library.
432/// - `"multiplatform"`: reserved for the KMP stage (Phase 3 follow-up).
433#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
434#[serde(rename_all = "lowercase")]
435pub enum KotlinTarget {
436 #[default]
437 Jvm,
438 Native,
439 // Multiplatform — Phase 3 KMP stage; placeholder so the enum is forward-compatible.
440 Multiplatform,
441}
442
443#[derive(Debug, Clone, Serialize, Deserialize)]
444pub struct KotlinConfig {
445 pub package: Option<String>,
446 #[serde(default)]
447 pub features: Option<Vec<String>>,
448 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
449 /// When set, this takes priority over the IR type-level serde_rename_all.
450 #[serde(default)]
451 pub serde_rename_all: Option<String>,
452 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
453 /// desired binding field name. Applied after automatic keyword escaping.
454 #[serde(default)]
455 pub rename_fields: HashMap<String, String>,
456 /// Functions to exclude from Kotlin binding generation.
457 #[serde(default)]
458 pub exclude_functions: Vec<String>,
459 /// Types to exclude from Kotlin binding generation.
460 #[serde(default)]
461 pub exclude_types: Vec<String>,
462 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
463 /// commands across all pipelines (lint, test, build, etc.).
464 #[serde(default)]
465 pub run_wrapper: Option<String>,
466 /// Extra paths to append to default lint commands (format, check, typecheck).
467 #[serde(default)]
468 pub extra_lint_paths: Vec<String>,
469 /// Target platform for Kotlin output. `"jvm"` (default) emits source consuming
470 /// the Java/Panama FFM facade; `"native"` emits Kotlin/Native source consuming
471 /// the cbindgen C FFI library. `"multiplatform"` is reserved for the KMP stage.
472 #[serde(default)]
473 pub target: KotlinTarget,
474}
475
476/// Dart bridging style: FRB (default) or raw `dart:ffi`.
477#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
478#[serde(rename_all = "lowercase")]
479pub enum DartStyle {
480 /// flutter_rust_bridge — emits a Rust crate plus Dart wrappers using
481 /// FRB-generated bridge symbols. Default.
482 #[default]
483 Frb,
484 /// Raw `dart:ffi` over the cbindgen C ABI — emits Dart-only source that
485 /// loads the shared library at runtime. Cheaper to ship; loses FRB's
486 /// async ergonomics and freezed-style data classes.
487 Ffi,
488}
489
490#[derive(Debug, Clone, Default, Serialize, Deserialize)]
491pub struct DartConfig {
492 /// Dart pub.dev package name (e.g. `"my_package"`). Used as the `name` in
493 /// `pubspec.yaml`. Defaults to a snake_case derivation of the crate name.
494 #[serde(default)]
495 pub pubspec_name: Option<String>,
496 /// Dart library name (the `library` declaration). Defaults to the pubspec name.
497 #[serde(default)]
498 pub lib_name: Option<String>,
499 /// Dart package name override (e.g. for pub.dev scoped packages).
500 #[serde(default)]
501 pub package_name: Option<String>,
502 /// Bridging style. `"frb"` (default) uses flutter_rust_bridge; `"ffi"` emits
503 /// raw `dart:ffi` source over the cbindgen C library.
504 #[serde(default)]
505 pub style: DartStyle,
506 /// flutter_rust_bridge version to pin in generated pubspec.yaml.
507 /// Defaults to `template_versions::cargo::FLUTTER_RUST_BRIDGE` when unset.
508 #[serde(default)]
509 pub frb_version: Option<String>,
510 /// Cargo features to enable on the binding crate.
511 #[serde(default)]
512 pub features: Option<Vec<String>>,
513 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
514 #[serde(default)]
515 pub serde_rename_all: Option<String>,
516 /// Per-field name remapping. Key is `TypeName.field_name`, value is the
517 /// desired binding field name. Applied after automatic keyword escaping.
518 #[serde(default)]
519 pub rename_fields: HashMap<String, String>,
520 /// Functions to exclude from Dart binding generation.
521 #[serde(default)]
522 pub exclude_functions: Vec<String>,
523 /// Types to exclude from Dart binding generation.
524 #[serde(default)]
525 pub exclude_types: Vec<String>,
526 /// Prefix wrapper for default tool invocations.
527 #[serde(default)]
528 pub run_wrapper: Option<String>,
529 /// Extra paths to append to default lint commands.
530 #[serde(default)]
531 pub extra_lint_paths: Vec<String>,
532 /// Override the core Cargo dependency name and path for the Dart binding crate.
533 /// When set, the binding `Cargo.toml` depends on this crate (resolved as
534 /// `../../../crates/<override>`) instead of the umbrella `[crate.name]`.
535 /// Defaults to unset.
536 #[serde(default)]
537 pub core_crate_override: Option<String>,
538 /// Keys to subtract from the merged `extra_dependencies` set for this
539 /// language only.
540 #[serde(default)]
541 pub exclude_extra_dependencies: Vec<String>,
542}
543
544#[derive(Debug, Clone, Default, Serialize, Deserialize)]
545pub struct SwiftConfig {
546 /// Swift module name (e.g. `"MyLibrary"`). Defaults to PascalCase of the crate name.
547 #[serde(default)]
548 pub module_name: Option<String>,
549 /// Swift package name. Defaults to the module name.
550 #[serde(default)]
551 pub package_name: Option<String>,
552 /// swift-bridge version. Defaults to `template_versions::cargo::SWIFT_BRIDGE` when unset.
553 #[serde(default)]
554 pub swift_bridge_version: Option<String>,
555 /// Minimum macOS deployment target. Defaults to `template_versions::toolchain::SWIFT_MIN_MACOS` when unset.
556 #[serde(default)]
557 pub min_macos_version: Option<String>,
558 /// Minimum iOS deployment target. Defaults to `template_versions::toolchain::SWIFT_MIN_IOS` when unset.
559 #[serde(default)]
560 pub min_ios_version: Option<String>,
561 /// Cargo features to enable on the binding crate.
562 #[serde(default)]
563 pub features: Option<Vec<String>>,
564 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
565 #[serde(default)]
566 pub serde_rename_all: Option<String>,
567 /// Per-field name remapping. Key is `TypeName.field_name`, value is the
568 /// desired binding field name. Applied after automatic keyword escaping.
569 #[serde(default)]
570 pub rename_fields: HashMap<String, String>,
571 /// Functions to exclude from Swift binding generation.
572 #[serde(default)]
573 pub exclude_functions: Vec<String>,
574 /// Types to exclude from Swift binding generation.
575 #[serde(default)]
576 pub exclude_types: Vec<String>,
577 /// Fields to exclude from Swift binding generation.
578 /// Format: `"TypeName.field_name"`.
579 #[serde(default)]
580 pub exclude_fields: Vec<String>,
581 /// Prefix wrapper for default tool invocations.
582 #[serde(default)]
583 pub run_wrapper: Option<String>,
584 /// Extra paths to append to default lint commands.
585 #[serde(default)]
586 pub extra_lint_paths: Vec<String>,
587 /// Override the core Cargo dependency name and path for the Swift binding crate.
588 /// When set, the binding `Cargo.toml` depends on this crate (resolved as
589 /// `../../../crates/<override>`) instead of the umbrella `[crate.name]`.
590 /// Defaults to unset.
591 #[serde(default)]
592 pub core_crate_override: Option<String>,
593 /// Keys to subtract from the merged `extra_dependencies` set for this
594 /// language only.
595 #[serde(default)]
596 pub exclude_extra_dependencies: Vec<String>,
597}
598
599#[derive(Debug, Clone, Serialize, Deserialize)]
600pub struct GleamConfig {
601 pub app_name: Option<String>,
602 /// Erlang atom name for @external(erlang, "<nif>", ...) lookups (e.g., "my_app_nif").
603 /// Defaults to the app_name.
604 #[serde(default)]
605 pub nif_module: Option<String>,
606 #[serde(default)]
607 pub features: Option<Vec<String>>,
608 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
609 /// When set, this takes priority over the IR type-level serde_rename_all.
610 #[serde(default)]
611 pub serde_rename_all: Option<String>,
612 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
613 /// desired binding field name. Applied after automatic keyword escaping.
614 #[serde(default)]
615 pub rename_fields: HashMap<String, String>,
616 /// Functions to exclude from Gleam binding generation.
617 #[serde(default)]
618 pub exclude_functions: Vec<String>,
619 /// Types to exclude from Gleam binding generation.
620 #[serde(default)]
621 pub exclude_types: Vec<String>,
622 /// Prefix wrapper for default tool invocations.
623 #[serde(default)]
624 pub run_wrapper: Option<String>,
625 /// Extra paths to append to default lint commands.
626 #[serde(default)]
627 pub extra_lint_paths: Vec<String>,
628 /// Per-`element_type` Gleam record-constructor recipes used by the e2e
629 /// generator when emitting `json_object` arg literals. Each entry maps a
630 /// fixture-side `element_type` string (e.g. `"BatchFileItem"`) to a
631 /// structured constructor description that the codegen interpolates per
632 /// JSON-array item. Without an entry the codegen falls back to the
633 /// `json_object_wrapper` (or a plain `json_to_gleam`).
634 ///
635 /// Example:
636 ///
637 /// ```toml
638 /// [[crates.gleam.element_constructors]]
639 /// element_type = "BatchFileItem"
640 /// constructor = "kreuzberg.BatchFileItem"
641 /// [[crates.gleam.element_constructors.fields]]
642 /// gleam_field = "path"
643 /// kind = "file_path"
644 /// json_field = "path"
645 /// [[crates.gleam.element_constructors.fields]]
646 /// gleam_field = "config"
647 /// kind = "literal"
648 /// value = "option.None"
649 /// ```
650 #[serde(default)]
651 pub element_constructors: Vec<GleamElementConstructor>,
652 /// Optional Gleam expression template used to wrap `json_object` arg
653 /// values when no `element_type` recipe matches. The placeholder
654 /// `{json}` is replaced with a Gleam string literal containing the JSON
655 /// form of the arg value, allowing the downstream's Gleam binding to do
656 /// its own parsing.
657 ///
658 /// Example:
659 ///
660 /// ```toml
661 /// [crates.gleam]
662 /// json_object_wrapper = "kreuzberg.config_from_json_string({json})"
663 /// ```
664 ///
665 /// When `None`, the codegen emits `{json}` verbatim (a plain Gleam
666 /// string), matching the iter15 default.
667 #[serde(default)]
668 pub json_object_wrapper: Option<String>,
669}
670
671/// One per-`element_type` Gleam record-constructor recipe. Keyed by the
672/// fixture-side `element_type` string and consumed by the e2e Gleam codegen
673/// when building `json_object` arg literals.
674#[derive(Debug, Clone, Serialize, Deserialize)]
675pub struct GleamElementConstructor {
676 /// Fixture-side `element_type` value this recipe applies to (e.g.
677 /// `"BatchFileItem"`).
678 pub element_type: String,
679 /// Fully-qualified Gleam constructor identifier (e.g.
680 /// `"kreuzberg.BatchFileItem"`). Emitted verbatim before the `(...)` field
681 /// list.
682 pub constructor: String,
683 /// Ordered list of fields to emit inside the constructor's `(...)` block,
684 /// in argument-position order. Each field describes how its value is
685 /// derived from the per-item JSON object.
686 pub fields: Vec<GleamElementField>,
687}
688
689/// One field inside a [`GleamElementConstructor`]'s argument list.
690///
691/// `kind` selects the source/encoding strategy:
692/// * `"file_path"` — read `json_field` from the JSON object as a string,
693/// prefix with the configured `test_documents_dir` when the value does not
694/// start with `/`, and emit as a Gleam string literal.
695/// * `"byte_array"` — read `json_field` from the JSON object as a JSON
696/// `Array(Number)` and emit as a Gleam BitArray literal `<<n1, n2, …>>`.
697/// * `"string"` — read `json_field` as a string, emit as a Gleam string
698/// literal; falls back to `default` (or empty) if missing.
699/// * `"literal"` — emit `value` verbatim (no JSON lookup). Use for
700/// constant fields like `config: option.None`.
701#[derive(Debug, Clone, Serialize, Deserialize)]
702pub struct GleamElementField {
703 /// Gleam record field name (e.g. `"path"`, `"config"`).
704 pub gleam_field: String,
705 /// Source/encoding strategy. See struct doc.
706 pub kind: String,
707 /// JSON object key to read, when `kind` is one of the JSON-driven
708 /// strategies. Required for `"file_path"`, `"byte_array"`, `"string"`;
709 /// ignored for `"literal"`.
710 #[serde(default)]
711 pub json_field: Option<String>,
712 /// Default Gleam expression when `json_field` is missing/null. Only
713 /// honoured by the `"string"` strategy today.
714 #[serde(default)]
715 pub default: Option<String>,
716 /// Verbatim Gleam expression to emit when `kind = "literal"`.
717 #[serde(default)]
718 pub value: Option<String>,
719}
720
721#[derive(Debug, Clone, Serialize, Deserialize)]
722pub struct ZigConfig {
723 pub module_name: Option<String>,
724 #[serde(default)]
725 pub features: Option<Vec<String>>,
726 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
727 /// When set, this takes priority over the IR type-level serde_rename_all.
728 #[serde(default)]
729 pub serde_rename_all: Option<String>,
730 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
731 /// desired binding field name. Applied after automatic keyword escaping.
732 #[serde(default)]
733 pub rename_fields: HashMap<String, String>,
734 /// Functions to exclude from Zig binding generation.
735 #[serde(default)]
736 pub exclude_functions: Vec<String>,
737 /// Types to exclude from Zig binding generation.
738 #[serde(default)]
739 pub exclude_types: Vec<String>,
740 /// Prefix wrapper for default tool invocations.
741 #[serde(default)]
742 pub run_wrapper: Option<String>,
743 /// Extra paths to append to default lint commands.
744 #[serde(default)]
745 pub extra_lint_paths: Vec<String>,
746}
747
748#[derive(Debug, Clone, Serialize, Deserialize)]
749pub struct CSharpConfig {
750 pub namespace: Option<String>,
751 /// NuGet `<PackageId>` to publish under. When unset, falls back to `namespace`.
752 /// Use this when the published artifact id must differ from the C# `RootNamespace` —
753 /// e.g. when the unprefixed name is owned by a third party on nuget.org and
754 /// you publish under a vendor-prefixed id like `KreuzbergDev.<Lib>`.
755 #[serde(default)]
756 pub package_id: Option<String>,
757 pub target_framework: Option<String>,
758 #[serde(default)]
759 pub features: Option<Vec<String>>,
760 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
761 /// When set, this takes priority over the IR type-level serde_rename_all.
762 #[serde(default)]
763 pub serde_rename_all: Option<String>,
764 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
765 /// desired binding field name. Applied after automatic keyword escaping.
766 #[serde(default)]
767 pub rename_fields: HashMap<String, String>,
768 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
769 /// commands across all pipelines (lint, test, build, etc.).
770 #[serde(default)]
771 pub run_wrapper: Option<String>,
772 /// Extra paths to append to default lint commands (format, check, typecheck).
773 /// Ignored when project_file is set.
774 #[serde(default)]
775 pub extra_lint_paths: Vec<String>,
776 /// Project file for C# (e.g., "MyProject.csproj", "MySolution.sln"). When set, default
777 /// lint/build/test commands target this file instead of the output directory.
778 #[serde(default)]
779 pub project_file: Option<String>,
780 /// Functions to exclude from C# binding generation (e.g., functions not present in the
781 /// C FFI layer). Excluded functions are omitted from both NativeMethods.cs and the
782 /// wrapper class.
783 #[serde(default)]
784 pub exclude_functions: Vec<String>,
785}
786
787#[derive(Debug, Clone, Serialize, Deserialize)]
788pub struct RConfig {
789 pub package_name: Option<String>,
790 #[serde(default)]
791 pub features: Option<Vec<String>>,
792 /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
793 /// When set, this takes priority over the IR type-level serde_rename_all.
794 #[serde(default)]
795 pub serde_rename_all: Option<String>,
796 /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
797 /// desired binding field name. Applied after automatic keyword escaping.
798 #[serde(default)]
799 pub rename_fields: HashMap<String, String>,
800 /// Prefix wrapper for default tool invocations. When set, prepends this string to default
801 /// commands across all pipelines (lint, test, build, etc.).
802 #[serde(default)]
803 pub run_wrapper: Option<String>,
804 /// Extra paths to append to default lint commands (format, check, typecheck).
805 #[serde(default)]
806 pub extra_lint_paths: Vec<String>,
807}
808
809/// Custom modules that alef should declare (mod X;) but not generate.
810/// These are hand-written modules imported by the generated lib.rs.
811#[derive(Debug, Clone, Default, Serialize, Deserialize)]
812pub struct CustomModulesConfig {
813 #[serde(default)]
814 pub python: Vec<String>,
815 #[serde(default)]
816 pub node: Vec<String>,
817 #[serde(default)]
818 pub ruby: Vec<String>,
819 #[serde(default)]
820 pub php: Vec<String>,
821 #[serde(default)]
822 pub elixir: Vec<String>,
823 #[serde(default)]
824 pub wasm: Vec<String>,
825 #[serde(default)]
826 pub ffi: Vec<String>,
827 #[serde(default)]
828 pub go: Vec<String>,
829 #[serde(default)]
830 pub java: Vec<String>,
831 #[serde(default)]
832 pub csharp: Vec<String>,
833 #[serde(default)]
834 pub r: Vec<String>,
835}
836
837impl CustomModulesConfig {
838 pub fn for_language(&self, lang: Language) -> &[String] {
839 match lang {
840 Language::Python => &self.python,
841 Language::Node => &self.node,
842 Language::Ruby => &self.ruby,
843 Language::Php => &self.php,
844 Language::Elixir => &self.elixir,
845 Language::Wasm => &self.wasm,
846 Language::Ffi => &self.ffi,
847 Language::Go => &self.go,
848 Language::Java => &self.java,
849 Language::Csharp => &self.csharp,
850 Language::R => &self.r,
851 Language::Rust => &[], // Rust doesn't need custom modules (no binding crate)
852 Language::Kotlin | Language::Swift | Language::Dart | Language::Gleam | Language::Zig | Language::C => &[],
853 }
854 }
855}
856
857/// Custom classes/functions from hand-written modules to register in module init.
858#[derive(Debug, Clone, Default, Serialize, Deserialize)]
859pub struct CustomRegistration {
860 #[serde(default)]
861 pub classes: Vec<String>,
862 #[serde(default)]
863 pub functions: Vec<String>,
864 #[serde(default)]
865 pub init_calls: Vec<String>,
866}
867
868/// Per-language custom registrations.
869#[derive(Debug, Clone, Default, Serialize, Deserialize)]
870pub struct CustomRegistrationsConfig {
871 #[serde(default)]
872 pub python: Option<CustomRegistration>,
873 #[serde(default)]
874 pub node: Option<CustomRegistration>,
875 #[serde(default)]
876 pub ruby: Option<CustomRegistration>,
877 #[serde(default)]
878 pub php: Option<CustomRegistration>,
879 #[serde(default)]
880 pub elixir: Option<CustomRegistration>,
881 #[serde(default)]
882 pub wasm: Option<CustomRegistration>,
883}
884
885impl CustomRegistrationsConfig {
886 pub fn for_language(&self, lang: Language) -> Option<&CustomRegistration> {
887 match lang {
888 Language::Python => self.python.as_ref(),
889 Language::Node => self.node.as_ref(),
890 Language::Ruby => self.ruby.as_ref(),
891 Language::Php => self.php.as_ref(),
892 Language::Elixir => self.elixir.as_ref(),
893 Language::Wasm => self.wasm.as_ref(),
894 _ => None,
895 }
896 }
897}