Skip to main content

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    /// Feature gate for ext-php-rs (default: "extension-module").
149    /// All generated code is wrapped in `#[cfg(feature = "...")]`.
150    #[serde(default)]
151    pub feature_gate: Option<String>,
152    /// Output directory for generated PHP facade / stubs (e.g., `packages/php/src/`).
153    #[serde(default)]
154    pub stubs: Option<StubsConfig>,
155    #[serde(default)]
156    pub features: Option<Vec<String>>,
157    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
158    /// When set, this takes priority over the IR type-level serde_rename_all.
159    #[serde(default)]
160    pub serde_rename_all: Option<String>,
161    /// Functions to exclude from PHP binding generation.
162    #[serde(default)]
163    pub exclude_functions: Vec<String>,
164    /// Types to exclude from PHP binding generation.
165    #[serde(default)]
166    pub exclude_types: Vec<String>,
167    /// Additional Cargo dependencies for this language's binding crate only.
168    #[serde(default)]
169    pub extra_dependencies: HashMap<String, toml::Value>,
170    /// Override the scaffold output directory for this language's Cargo.toml and package files.
171    #[serde(default)]
172    pub scaffold_output: Option<PathBuf>,
173    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
174    /// desired binding field name. Applied after automatic keyword escaping.
175    #[serde(default)]
176    pub rename_fields: HashMap<String, String>,
177    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
178    /// commands across all pipelines (lint, test, build, etc.).
179    #[serde(default)]
180    pub run_wrapper: Option<String>,
181    /// Extra paths to append to default lint commands (format, check, typecheck).
182    #[serde(default)]
183    pub extra_lint_paths: Vec<String>,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct ElixirConfig {
188    pub app_name: Option<String>,
189    #[serde(default)]
190    pub features: Option<Vec<String>>,
191    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
192    /// When set, this takes priority over the IR type-level serde_rename_all.
193    #[serde(default)]
194    pub serde_rename_all: Option<String>,
195    /// Functions to exclude from Elixir NIF generation.
196    #[serde(default)]
197    pub exclude_functions: Vec<String>,
198    /// Types to exclude from Elixir NIF generation.
199    #[serde(default)]
200    pub exclude_types: Vec<String>,
201    /// Additional Cargo dependencies for this language's binding crate only.
202    #[serde(default)]
203    pub extra_dependencies: HashMap<String, toml::Value>,
204    /// Override the scaffold output directory for this language's Cargo.toml and package files.
205    #[serde(default)]
206    pub scaffold_output: Option<PathBuf>,
207    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
208    /// desired binding field name. Applied after automatic keyword escaping.
209    #[serde(default)]
210    pub rename_fields: HashMap<String, String>,
211    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
212    /// commands across all pipelines (lint, test, build, etc.).
213    #[serde(default)]
214    pub run_wrapper: Option<String>,
215    /// Extra paths to append to default lint commands (format, check, typecheck).
216    #[serde(default)]
217    pub extra_lint_paths: Vec<String>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
221pub struct WasmConfig {
222    #[serde(default)]
223    pub exclude_functions: Vec<String>,
224    #[serde(default)]
225    pub exclude_types: Vec<String>,
226    #[serde(default)]
227    pub type_overrides: HashMap<String, String>,
228    #[serde(default)]
229    pub features: Option<Vec<String>>,
230    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
231    /// When set, this takes priority over the IR type-level serde_rename_all.
232    #[serde(default)]
233    pub serde_rename_all: Option<String>,
234    /// Prefix for generated type names (e.g. "Wasm" produces `WasmConversionOptions`).
235    /// Defaults to `"Wasm"`.
236    #[serde(default)]
237    pub type_prefix: Option<String>,
238    /// Functions to exclude from the public TypeScript re-export (index.ts) while still
239    /// generating the Rust binding. Use this when a custom module provides a wrapper.
240    #[serde(default)]
241    pub exclude_reexports: Vec<String>,
242    /// Wide-character C functions to shim for WASM external scanner interop.
243    #[serde(default)]
244    pub env_shims: Vec<String>,
245    /// Additional Cargo dependencies for the WASM binding crate only.
246    #[serde(default)]
247    pub extra_dependencies: HashMap<String, toml::Value>,
248    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
249    /// desired binding field name. Applied after automatic keyword escaping.
250    #[serde(default)]
251    pub rename_fields: HashMap<String, String>,
252    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
253    /// commands across all pipelines (lint, test, build, etc.).
254    #[serde(default)]
255    pub run_wrapper: Option<String>,
256    /// Extra paths to append to default lint commands (format, check, typecheck).
257    #[serde(default)]
258    pub extra_lint_paths: Vec<String>,
259    /// Override the core Cargo dependency name and path for the WASM binding crate.
260    /// When set, the binding `Cargo.toml` depends on this crate (resolved as
261    /// `../<override>`) instead of the umbrella `[crate.name]`. Use this to point
262    /// the WASM binding at a wasm-safe sub-crate while other languages keep the
263    /// facade. Defaults to unset.
264    #[serde(default)]
265    pub core_crate_override: Option<String>,
266    /// Keys to subtract from the merged `extra_dependencies` set for this
267    /// language only. Useful when `[crate.extra_dependencies]` lists sibling
268    /// crates that the WASM target cannot link.
269    #[serde(default)]
270    pub exclude_extra_dependencies: Vec<String>,
271}
272
273#[derive(Debug, Clone, Serialize, Deserialize)]
274pub struct FfiConfig {
275    pub prefix: Option<String>,
276    #[serde(default = "default_error_style")]
277    pub error_style: String,
278    pub header_name: Option<String>,
279    /// Native library name for Go cgo/Java Panama/C# P/Invoke (e.g., "ts_pack_ffi").
280    /// Defaults to `{prefix}_ffi`.
281    #[serde(default)]
282    pub lib_name: Option<String>,
283    /// If true, generate visitor/callback FFI support.
284    #[serde(default)]
285    pub visitor_callbacks: bool,
286    #[serde(default)]
287    pub features: Option<Vec<String>>,
288    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
289    /// When set, this takes priority over the IR type-level serde_rename_all.
290    #[serde(default)]
291    pub serde_rename_all: Option<String>,
292    /// Functions to exclude from FFI binding generation.
293    #[serde(default)]
294    pub exclude_functions: Vec<String>,
295    /// Types to exclude from FFI binding generation.
296    #[serde(default)]
297    pub exclude_types: Vec<String>,
298    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
299    /// desired binding field name. Applied after automatic keyword escaping.
300    #[serde(default)]
301    pub rename_fields: HashMap<String, String>,
302}
303
304fn default_error_style() -> String {
305    "last_error".to_string()
306}
307
308#[derive(Debug, Clone, Serialize, Deserialize)]
309pub struct GoConfig {
310    pub module: Option<String>,
311    /// Override the Go package name (default: derived from module path)
312    pub package_name: Option<String>,
313    #[serde(default)]
314    pub features: Option<Vec<String>>,
315    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
316    /// When set, this takes priority over the IR type-level serde_rename_all.
317    #[serde(default)]
318    pub serde_rename_all: Option<String>,
319    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
320    /// desired binding field name. Applied after automatic keyword escaping.
321    #[serde(default)]
322    pub rename_fields: HashMap<String, String>,
323    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
324    /// commands across all pipelines (lint, test, build, etc.).
325    #[serde(default)]
326    pub run_wrapper: Option<String>,
327    /// Extra paths to append to default lint commands (format, check, typecheck).
328    #[serde(default)]
329    pub extra_lint_paths: Vec<String>,
330}
331
332#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct JavaConfig {
334    pub package: Option<String>,
335    #[serde(default = "default_java_ffi_style")]
336    pub ffi_style: String,
337    #[serde(default)]
338    pub features: Option<Vec<String>>,
339    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
340    /// When set, this takes priority over the IR type-level serde_rename_all.
341    #[serde(default)]
342    pub serde_rename_all: Option<String>,
343    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
344    /// desired binding field name. Applied after automatic keyword escaping.
345    #[serde(default)]
346    pub rename_fields: HashMap<String, String>,
347    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
348    /// commands across all pipelines (lint, test, build, etc.).
349    #[serde(default)]
350    pub run_wrapper: Option<String>,
351    /// Extra paths to append to default lint commands (format, check, typecheck).
352    /// Ignored when project_file is set.
353    #[serde(default)]
354    pub extra_lint_paths: Vec<String>,
355    /// Project file for Maven/Gradle (e.g., "pom.xml", "build.gradle"). When set, default
356    /// lint/build/test commands target this file instead of the output directory.
357    #[serde(default)]
358    pub project_file: Option<String>,
359}
360
361fn default_java_ffi_style() -> String {
362    "panama".to_string()
363}
364
365/// Target platform for Kotlin code generation.
366///
367/// - `"jvm"` (default): emits source consuming the Java/Panama FFM facade.
368/// - `"native"`: emits Kotlin/Native source consuming the cbindgen C FFI library.
369/// - `"multiplatform"`: reserved for the KMP stage (Phase 3 follow-up).
370#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
371#[serde(rename_all = "lowercase")]
372pub enum KotlinTarget {
373    #[default]
374    Jvm,
375    Native,
376    // Multiplatform — Phase 3 KMP stage; placeholder so the enum is forward-compatible.
377    Multiplatform,
378}
379
380#[derive(Debug, Clone, Serialize, Deserialize)]
381pub struct KotlinConfig {
382    pub package: Option<String>,
383    #[serde(default)]
384    pub features: Option<Vec<String>>,
385    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
386    /// When set, this takes priority over the IR type-level serde_rename_all.
387    #[serde(default)]
388    pub serde_rename_all: Option<String>,
389    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
390    /// desired binding field name. Applied after automatic keyword escaping.
391    #[serde(default)]
392    pub rename_fields: HashMap<String, String>,
393    /// Functions to exclude from Kotlin binding generation.
394    #[serde(default)]
395    pub exclude_functions: Vec<String>,
396    /// Types to exclude from Kotlin binding generation.
397    #[serde(default)]
398    pub exclude_types: Vec<String>,
399    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
400    /// commands across all pipelines (lint, test, build, etc.).
401    #[serde(default)]
402    pub run_wrapper: Option<String>,
403    /// Extra paths to append to default lint commands (format, check, typecheck).
404    #[serde(default)]
405    pub extra_lint_paths: Vec<String>,
406    /// Target platform for Kotlin output. `"jvm"` (default) emits source consuming
407    /// the Java/Panama FFM facade; `"native"` emits Kotlin/Native source consuming
408    /// the cbindgen C FFI library. `"multiplatform"` is reserved for the KMP stage.
409    #[serde(default)]
410    pub target: KotlinTarget,
411}
412
413/// Dart bridging style: FRB (default) or raw `dart:ffi`.
414#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
415#[serde(rename_all = "lowercase")]
416pub enum DartStyle {
417    /// flutter_rust_bridge — emits a Rust crate plus Dart wrappers using
418    /// FRB-generated bridge symbols. Default.
419    #[default]
420    Frb,
421    /// Raw `dart:ffi` over the cbindgen C ABI — emits Dart-only source that
422    /// loads the shared library at runtime. Cheaper to ship; loses FRB's
423    /// async ergonomics and freezed-style data classes.
424    Ffi,
425}
426
427#[derive(Debug, Clone, Default, Serialize, Deserialize)]
428pub struct DartConfig {
429    /// Dart pub.dev package name (e.g. `"my_package"`). Used as the `name` in
430    /// `pubspec.yaml`. Defaults to a snake_case derivation of the crate name.
431    #[serde(default)]
432    pub pubspec_name: Option<String>,
433    /// Dart library name (the `library` declaration). Defaults to the pubspec name.
434    #[serde(default)]
435    pub lib_name: Option<String>,
436    /// Dart package name override (e.g. for pub.dev scoped packages).
437    #[serde(default)]
438    pub package_name: Option<String>,
439    /// Bridging style. `"frb"` (default) uses flutter_rust_bridge; `"ffi"` emits
440    /// raw `dart:ffi` source over the cbindgen C library.
441    #[serde(default)]
442    pub style: DartStyle,
443    /// flutter_rust_bridge version to pin in generated pubspec.yaml.
444    /// Defaults to `template_versions::cargo::FLUTTER_RUST_BRIDGE` when unset.
445    #[serde(default)]
446    pub frb_version: Option<String>,
447    /// Cargo features to enable on the binding crate.
448    #[serde(default)]
449    pub features: Option<Vec<String>>,
450    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
451    #[serde(default)]
452    pub serde_rename_all: Option<String>,
453    /// Per-field name remapping. Key is `TypeName.field_name`, value is the
454    /// desired binding field name. Applied after automatic keyword escaping.
455    #[serde(default)]
456    pub rename_fields: HashMap<String, String>,
457    /// Functions to exclude from Dart binding generation.
458    #[serde(default)]
459    pub exclude_functions: Vec<String>,
460    /// Types to exclude from Dart binding generation.
461    #[serde(default)]
462    pub exclude_types: Vec<String>,
463    /// Prefix wrapper for default tool invocations.
464    #[serde(default)]
465    pub run_wrapper: Option<String>,
466    /// Extra paths to append to default lint commands.
467    #[serde(default)]
468    pub extra_lint_paths: Vec<String>,
469    /// Override the core Cargo dependency name and path for the Dart binding crate.
470    /// When set, the binding `Cargo.toml` depends on this crate (resolved as
471    /// `../../../crates/<override>`) instead of the umbrella `[crate.name]`.
472    /// Defaults to unset.
473    #[serde(default)]
474    pub core_crate_override: Option<String>,
475    /// Keys to subtract from the merged `extra_dependencies` set for this
476    /// language only.
477    #[serde(default)]
478    pub exclude_extra_dependencies: Vec<String>,
479}
480
481#[derive(Debug, Clone, Default, Serialize, Deserialize)]
482pub struct SwiftConfig {
483    /// Swift module name (e.g. `"MyLibrary"`). Defaults to PascalCase of the crate name.
484    #[serde(default)]
485    pub module_name: Option<String>,
486    /// Swift package name. Defaults to the module name.
487    #[serde(default)]
488    pub package_name: Option<String>,
489    /// swift-bridge version. Defaults to `template_versions::cargo::SWIFT_BRIDGE` when unset.
490    #[serde(default)]
491    pub swift_bridge_version: Option<String>,
492    /// Minimum macOS deployment target. Defaults to `template_versions::toolchain::SWIFT_MIN_MACOS` when unset.
493    #[serde(default)]
494    pub min_macos_version: Option<String>,
495    /// Minimum iOS deployment target. Defaults to `template_versions::toolchain::SWIFT_MIN_IOS` when unset.
496    #[serde(default)]
497    pub min_ios_version: Option<String>,
498    /// Cargo features to enable on the binding crate.
499    #[serde(default)]
500    pub features: Option<Vec<String>>,
501    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
502    #[serde(default)]
503    pub serde_rename_all: Option<String>,
504    /// Per-field name remapping. Key is `TypeName.field_name`, value is the
505    /// desired binding field name. Applied after automatic keyword escaping.
506    #[serde(default)]
507    pub rename_fields: HashMap<String, String>,
508    /// Functions to exclude from Swift binding generation.
509    #[serde(default)]
510    pub exclude_functions: Vec<String>,
511    /// Types to exclude from Swift binding generation.
512    #[serde(default)]
513    pub exclude_types: Vec<String>,
514    /// Fields to exclude from Swift binding generation.
515    /// Format: `"TypeName.field_name"`.
516    #[serde(default)]
517    pub exclude_fields: Vec<String>,
518    /// Prefix wrapper for default tool invocations.
519    #[serde(default)]
520    pub run_wrapper: Option<String>,
521    /// Extra paths to append to default lint commands.
522    #[serde(default)]
523    pub extra_lint_paths: Vec<String>,
524    /// Override the core Cargo dependency name and path for the Swift binding crate.
525    /// When set, the binding `Cargo.toml` depends on this crate (resolved as
526    /// `../../../crates/<override>`) instead of the umbrella `[crate.name]`.
527    /// Defaults to unset.
528    #[serde(default)]
529    pub core_crate_override: Option<String>,
530    /// Keys to subtract from the merged `extra_dependencies` set for this
531    /// language only.
532    #[serde(default)]
533    pub exclude_extra_dependencies: Vec<String>,
534}
535
536#[derive(Debug, Clone, Serialize, Deserialize)]
537pub struct GleamConfig {
538    pub app_name: Option<String>,
539    /// Erlang atom name for @external(erlang, "<nif>", ...) lookups (e.g., "my_app_nif").
540    /// Defaults to the app_name.
541    #[serde(default)]
542    pub nif_module: Option<String>,
543    #[serde(default)]
544    pub features: Option<Vec<String>>,
545    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
546    /// When set, this takes priority over the IR type-level serde_rename_all.
547    #[serde(default)]
548    pub serde_rename_all: Option<String>,
549    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
550    /// desired binding field name. Applied after automatic keyword escaping.
551    #[serde(default)]
552    pub rename_fields: HashMap<String, String>,
553    /// Functions to exclude from Gleam binding generation.
554    #[serde(default)]
555    pub exclude_functions: Vec<String>,
556    /// Types to exclude from Gleam binding generation.
557    #[serde(default)]
558    pub exclude_types: Vec<String>,
559    /// Prefix wrapper for default tool invocations.
560    #[serde(default)]
561    pub run_wrapper: Option<String>,
562    /// Extra paths to append to default lint commands.
563    #[serde(default)]
564    pub extra_lint_paths: Vec<String>,
565}
566
567#[derive(Debug, Clone, Serialize, Deserialize)]
568pub struct ZigConfig {
569    pub module_name: Option<String>,
570    #[serde(default)]
571    pub features: Option<Vec<String>>,
572    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
573    /// When set, this takes priority over the IR type-level serde_rename_all.
574    #[serde(default)]
575    pub serde_rename_all: Option<String>,
576    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
577    /// desired binding field name. Applied after automatic keyword escaping.
578    #[serde(default)]
579    pub rename_fields: HashMap<String, String>,
580    /// Functions to exclude from Zig binding generation.
581    #[serde(default)]
582    pub exclude_functions: Vec<String>,
583    /// Types to exclude from Zig binding generation.
584    #[serde(default)]
585    pub exclude_types: Vec<String>,
586    /// Prefix wrapper for default tool invocations.
587    #[serde(default)]
588    pub run_wrapper: Option<String>,
589    /// Extra paths to append to default lint commands.
590    #[serde(default)]
591    pub extra_lint_paths: Vec<String>,
592}
593
594#[derive(Debug, Clone, Serialize, Deserialize)]
595pub struct CSharpConfig {
596    pub namespace: Option<String>,
597    /// NuGet `<PackageId>` to publish under. When unset, falls back to `namespace`.
598    /// Use this when the published artifact id must differ from the C# `RootNamespace` —
599    /// e.g. when the unprefixed name is owned by a third party on nuget.org and
600    /// you publish under a vendor-prefixed id like `KreuzbergDev.<Lib>`.
601    #[serde(default)]
602    pub package_id: Option<String>,
603    pub target_framework: Option<String>,
604    #[serde(default)]
605    pub features: Option<Vec<String>>,
606    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
607    /// When set, this takes priority over the IR type-level serde_rename_all.
608    #[serde(default)]
609    pub serde_rename_all: Option<String>,
610    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
611    /// desired binding field name. Applied after automatic keyword escaping.
612    #[serde(default)]
613    pub rename_fields: HashMap<String, String>,
614    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
615    /// commands across all pipelines (lint, test, build, etc.).
616    #[serde(default)]
617    pub run_wrapper: Option<String>,
618    /// Extra paths to append to default lint commands (format, check, typecheck).
619    /// Ignored when project_file is set.
620    #[serde(default)]
621    pub extra_lint_paths: Vec<String>,
622    /// Project file for C# (e.g., "MyProject.csproj", "MySolution.sln"). When set, default
623    /// lint/build/test commands target this file instead of the output directory.
624    #[serde(default)]
625    pub project_file: Option<String>,
626}
627
628#[derive(Debug, Clone, Serialize, Deserialize)]
629pub struct RConfig {
630    pub package_name: Option<String>,
631    #[serde(default)]
632    pub features: Option<Vec<String>>,
633    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
634    /// When set, this takes priority over the IR type-level serde_rename_all.
635    #[serde(default)]
636    pub serde_rename_all: Option<String>,
637    /// Per-field name remapping for this language. Key is `TypeName.field_name`, value is the
638    /// desired binding field name. Applied after automatic keyword escaping.
639    #[serde(default)]
640    pub rename_fields: HashMap<String, String>,
641    /// Prefix wrapper for default tool invocations. When set, prepends this string to default
642    /// commands across all pipelines (lint, test, build, etc.).
643    #[serde(default)]
644    pub run_wrapper: Option<String>,
645    /// Extra paths to append to default lint commands (format, check, typecheck).
646    #[serde(default)]
647    pub extra_lint_paths: Vec<String>,
648}
649
650/// Custom modules that alef should declare (mod X;) but not generate.
651/// These are hand-written modules imported by the generated lib.rs.
652#[derive(Debug, Clone, Default, Serialize, Deserialize)]
653pub struct CustomModulesConfig {
654    #[serde(default)]
655    pub python: Vec<String>,
656    #[serde(default)]
657    pub node: Vec<String>,
658    #[serde(default)]
659    pub ruby: Vec<String>,
660    #[serde(default)]
661    pub php: Vec<String>,
662    #[serde(default)]
663    pub elixir: Vec<String>,
664    #[serde(default)]
665    pub wasm: Vec<String>,
666    #[serde(default)]
667    pub ffi: Vec<String>,
668    #[serde(default)]
669    pub go: Vec<String>,
670    #[serde(default)]
671    pub java: Vec<String>,
672    #[serde(default)]
673    pub csharp: Vec<String>,
674    #[serde(default)]
675    pub r: Vec<String>,
676}
677
678impl CustomModulesConfig {
679    pub fn for_language(&self, lang: Language) -> &[String] {
680        match lang {
681            Language::Python => &self.python,
682            Language::Node => &self.node,
683            Language::Ruby => &self.ruby,
684            Language::Php => &self.php,
685            Language::Elixir => &self.elixir,
686            Language::Wasm => &self.wasm,
687            Language::Ffi => &self.ffi,
688            Language::Go => &self.go,
689            Language::Java => &self.java,
690            Language::Csharp => &self.csharp,
691            Language::R => &self.r,
692            Language::Rust => &[], // Rust doesn't need custom modules (no binding crate)
693            Language::Kotlin | Language::Swift | Language::Dart | Language::Gleam | Language::Zig => &[],
694        }
695    }
696}
697
698/// Custom classes/functions from hand-written modules to register in module init.
699#[derive(Debug, Clone, Default, Serialize, Deserialize)]
700pub struct CustomRegistration {
701    #[serde(default)]
702    pub classes: Vec<String>,
703    #[serde(default)]
704    pub functions: Vec<String>,
705    #[serde(default)]
706    pub init_calls: Vec<String>,
707}
708
709/// Per-language custom registrations.
710#[derive(Debug, Clone, Default, Serialize, Deserialize)]
711pub struct CustomRegistrationsConfig {
712    #[serde(default)]
713    pub python: Option<CustomRegistration>,
714    #[serde(default)]
715    pub node: Option<CustomRegistration>,
716    #[serde(default)]
717    pub ruby: Option<CustomRegistration>,
718    #[serde(default)]
719    pub php: Option<CustomRegistration>,
720    #[serde(default)]
721    pub elixir: Option<CustomRegistration>,
722    #[serde(default)]
723    pub wasm: Option<CustomRegistration>,
724}
725
726impl CustomRegistrationsConfig {
727    pub fn for_language(&self, lang: Language) -> Option<&CustomRegistration> {
728        match lang {
729            Language::Python => self.python.as_ref(),
730            Language::Node => self.node.as_ref(),
731            Language::Ruby => self.ruby.as_ref(),
732            Language::Php => self.php.as_ref(),
733            Language::Elixir => self.elixir.as_ref(),
734            Language::Wasm => self.wasm.as_ref(),
735            _ => None,
736        }
737    }
738}