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}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct StubsConfig {
29    pub output: PathBuf,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct NodeConfig {
34    pub package_name: Option<String>,
35    /// Per-language feature override. When set, these features are used instead of
36    /// `[crate] features` for this language's binding crate.
37    #[serde(default)]
38    pub features: Option<Vec<String>>,
39    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
40    /// When set, this takes priority over the IR type-level serde_rename_all.
41    #[serde(default)]
42    pub serde_rename_all: Option<String>,
43    /// Prefix for generated type names (e.g. "Js" produces `JsConversionOptions`).
44    /// Defaults to `"Js"`.
45    #[serde(default)]
46    pub type_prefix: Option<String>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct RubyConfig {
51    pub gem_name: Option<String>,
52    pub stubs: Option<StubsConfig>,
53    /// Per-language feature override. When set, these features are used instead of
54    /// `[crate] features` for this language's binding crate.
55    #[serde(default)]
56    pub features: Option<Vec<String>>,
57    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
58    /// When set, this takes priority over the IR type-level serde_rename_all.
59    #[serde(default)]
60    pub serde_rename_all: Option<String>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct PhpConfig {
65    pub extension_name: Option<String>,
66    /// Feature gate for ext-php-rs (default: "extension-module").
67    /// All generated code is wrapped in `#[cfg(feature = "...")]`.
68    #[serde(default)]
69    pub feature_gate: Option<String>,
70    /// Output directory for generated PHP facade / stubs (e.g., `packages/php/src/`).
71    #[serde(default)]
72    pub stubs: Option<StubsConfig>,
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    /// Functions to exclude from PHP binding generation.
80    #[serde(default)]
81    pub exclude_functions: Vec<String>,
82    /// Types to exclude from PHP binding generation.
83    #[serde(default)]
84    pub exclude_types: Vec<String>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct ElixirConfig {
89    pub app_name: Option<String>,
90    #[serde(default)]
91    pub features: Option<Vec<String>>,
92    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
93    /// When set, this takes priority over the IR type-level serde_rename_all.
94    #[serde(default)]
95    pub serde_rename_all: Option<String>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct WasmConfig {
100    #[serde(default)]
101    pub exclude_functions: Vec<String>,
102    #[serde(default)]
103    pub exclude_types: Vec<String>,
104    #[serde(default)]
105    pub type_overrides: HashMap<String, String>,
106    #[serde(default)]
107    pub features: Option<Vec<String>>,
108    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
109    /// When set, this takes priority over the IR type-level serde_rename_all.
110    #[serde(default)]
111    pub serde_rename_all: Option<String>,
112    /// Prefix for generated type names (e.g. "Wasm" produces `WasmConversionOptions`).
113    /// Defaults to `"Wasm"`.
114    #[serde(default)]
115    pub type_prefix: Option<String>,
116    /// Functions to exclude from the public TypeScript re-export (index.ts) while still
117    /// generating the Rust binding. Use this when a custom module provides a wrapper.
118    #[serde(default)]
119    pub exclude_reexports: Vec<String>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct FfiConfig {
124    pub prefix: Option<String>,
125    #[serde(default = "default_error_style")]
126    pub error_style: String,
127    pub header_name: Option<String>,
128    /// Native library name for Go cgo/Java Panama/C# P/Invoke (e.g., "ts_pack_ffi").
129    /// Defaults to `{prefix}_ffi`.
130    #[serde(default)]
131    pub lib_name: Option<String>,
132    /// If true, generate visitor/callback FFI support.
133    #[serde(default)]
134    pub visitor_callbacks: bool,
135    #[serde(default)]
136    pub features: Option<Vec<String>>,
137    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
138    /// When set, this takes priority over the IR type-level serde_rename_all.
139    #[serde(default)]
140    pub serde_rename_all: Option<String>,
141}
142
143fn default_error_style() -> String {
144    "last_error".to_string()
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct GoConfig {
149    pub module: Option<String>,
150    /// Override the Go package name (default: derived from module path)
151    pub package_name: Option<String>,
152    #[serde(default)]
153    pub features: Option<Vec<String>>,
154    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
155    /// When set, this takes priority over the IR type-level serde_rename_all.
156    #[serde(default)]
157    pub serde_rename_all: Option<String>,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct JavaConfig {
162    pub package: Option<String>,
163    #[serde(default = "default_java_ffi_style")]
164    pub ffi_style: String,
165    #[serde(default)]
166    pub features: Option<Vec<String>>,
167    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
168    /// When set, this takes priority over the IR type-level serde_rename_all.
169    #[serde(default)]
170    pub serde_rename_all: Option<String>,
171}
172
173fn default_java_ffi_style() -> String {
174    "panama".to_string()
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct CSharpConfig {
179    pub namespace: Option<String>,
180    pub target_framework: Option<String>,
181    #[serde(default)]
182    pub features: Option<Vec<String>>,
183    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
184    /// When set, this takes priority over the IR type-level serde_rename_all.
185    #[serde(default)]
186    pub serde_rename_all: Option<String>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct RConfig {
191    pub package_name: Option<String>,
192    #[serde(default)]
193    pub features: Option<Vec<String>>,
194    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
195    /// When set, this takes priority over the IR type-level serde_rename_all.
196    #[serde(default)]
197    pub serde_rename_all: Option<String>,
198}
199
200/// Custom modules that alef should declare (mod X;) but not generate.
201/// These are hand-written modules imported by the generated lib.rs.
202#[derive(Debug, Clone, Default, Serialize, Deserialize)]
203pub struct CustomModulesConfig {
204    #[serde(default)]
205    pub python: Vec<String>,
206    #[serde(default)]
207    pub node: Vec<String>,
208    #[serde(default)]
209    pub ruby: Vec<String>,
210    #[serde(default)]
211    pub php: Vec<String>,
212    #[serde(default)]
213    pub elixir: Vec<String>,
214    #[serde(default)]
215    pub wasm: Vec<String>,
216    #[serde(default)]
217    pub ffi: Vec<String>,
218    #[serde(default)]
219    pub go: Vec<String>,
220    #[serde(default)]
221    pub java: Vec<String>,
222    #[serde(default)]
223    pub csharp: Vec<String>,
224    #[serde(default)]
225    pub r: Vec<String>,
226}
227
228impl CustomModulesConfig {
229    pub fn for_language(&self, lang: Language) -> &[String] {
230        match lang {
231            Language::Python => &self.python,
232            Language::Node => &self.node,
233            Language::Ruby => &self.ruby,
234            Language::Php => &self.php,
235            Language::Elixir => &self.elixir,
236            Language::Wasm => &self.wasm,
237            Language::Ffi => &self.ffi,
238            Language::Go => &self.go,
239            Language::Java => &self.java,
240            Language::Csharp => &self.csharp,
241            Language::R => &self.r,
242            Language::Rust => &[], // Rust doesn't need custom modules (no binding crate)
243        }
244    }
245}
246
247/// Custom classes/functions from hand-written modules to register in module init.
248#[derive(Debug, Clone, Default, Serialize, Deserialize)]
249pub struct CustomRegistration {
250    #[serde(default)]
251    pub classes: Vec<String>,
252    #[serde(default)]
253    pub functions: Vec<String>,
254    #[serde(default)]
255    pub init_calls: Vec<String>,
256}
257
258/// Per-language custom registrations.
259#[derive(Debug, Clone, Default, Serialize, Deserialize)]
260pub struct CustomRegistrationsConfig {
261    #[serde(default)]
262    pub python: Option<CustomRegistration>,
263    #[serde(default)]
264    pub node: Option<CustomRegistration>,
265    #[serde(default)]
266    pub ruby: Option<CustomRegistration>,
267    #[serde(default)]
268    pub php: Option<CustomRegistration>,
269    #[serde(default)]
270    pub elixir: Option<CustomRegistration>,
271    #[serde(default)]
272    pub wasm: Option<CustomRegistration>,
273}
274
275impl CustomRegistrationsConfig {
276    pub fn for_language(&self, lang: Language) -> Option<&CustomRegistration> {
277        match lang {
278            Language::Python => self.python.as_ref(),
279            Language::Node => self.node.as_ref(),
280            Language::Ruby => self.ruby.as_ref(),
281            Language::Php => self.php.as_ref(),
282            Language::Elixir => self.elixir.as_ref(),
283            Language::Wasm => self.wasm.as_ref(),
284            _ => None,
285        }
286    }
287}