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    /// Functions to exclude from Elixir NIF generation.
97    #[serde(default)]
98    pub exclude_functions: Vec<String>,
99    /// Types to exclude from Elixir NIF generation.
100    #[serde(default)]
101    pub exclude_types: Vec<String>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct WasmConfig {
106    #[serde(default)]
107    pub exclude_functions: Vec<String>,
108    #[serde(default)]
109    pub exclude_types: Vec<String>,
110    #[serde(default)]
111    pub type_overrides: HashMap<String, String>,
112    #[serde(default)]
113    pub features: Option<Vec<String>>,
114    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
115    /// When set, this takes priority over the IR type-level serde_rename_all.
116    #[serde(default)]
117    pub serde_rename_all: Option<String>,
118    /// Prefix for generated type names (e.g. "Wasm" produces `WasmConversionOptions`).
119    /// Defaults to `"Wasm"`.
120    #[serde(default)]
121    pub type_prefix: Option<String>,
122    /// Functions to exclude from the public TypeScript re-export (index.ts) while still
123    /// generating the Rust binding. Use this when a custom module provides a wrapper.
124    #[serde(default)]
125    pub exclude_reexports: Vec<String>,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct FfiConfig {
130    pub prefix: Option<String>,
131    #[serde(default = "default_error_style")]
132    pub error_style: String,
133    pub header_name: Option<String>,
134    /// Native library name for Go cgo/Java Panama/C# P/Invoke (e.g., "ts_pack_ffi").
135    /// Defaults to `{prefix}_ffi`.
136    #[serde(default)]
137    pub lib_name: Option<String>,
138    /// If true, generate visitor/callback FFI support.
139    #[serde(default)]
140    pub visitor_callbacks: bool,
141    #[serde(default)]
142    pub features: Option<Vec<String>>,
143    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
144    /// When set, this takes priority over the IR type-level serde_rename_all.
145    #[serde(default)]
146    pub serde_rename_all: Option<String>,
147}
148
149fn default_error_style() -> String {
150    "last_error".to_string()
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct GoConfig {
155    pub module: Option<String>,
156    /// Override the Go package name (default: derived from module path)
157    pub package_name: Option<String>,
158    #[serde(default)]
159    pub features: Option<Vec<String>>,
160    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
161    /// When set, this takes priority over the IR type-level serde_rename_all.
162    #[serde(default)]
163    pub serde_rename_all: Option<String>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct JavaConfig {
168    pub package: Option<String>,
169    #[serde(default = "default_java_ffi_style")]
170    pub ffi_style: String,
171    #[serde(default)]
172    pub features: Option<Vec<String>>,
173    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
174    /// When set, this takes priority over the IR type-level serde_rename_all.
175    #[serde(default)]
176    pub serde_rename_all: Option<String>,
177}
178
179fn default_java_ffi_style() -> String {
180    "panama".to_string()
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct CSharpConfig {
185    pub namespace: Option<String>,
186    pub target_framework: Option<String>,
187    #[serde(default)]
188    pub features: Option<Vec<String>>,
189    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
190    /// When set, this takes priority over the IR type-level serde_rename_all.
191    #[serde(default)]
192    pub serde_rename_all: Option<String>,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct RConfig {
197    pub package_name: Option<String>,
198    #[serde(default)]
199    pub features: Option<Vec<String>>,
200    /// Override the serde rename_all strategy for JSON field names (e.g. "camelCase", "snake_case").
201    /// When set, this takes priority over the IR type-level serde_rename_all.
202    #[serde(default)]
203    pub serde_rename_all: Option<String>,
204}
205
206/// Custom modules that alef should declare (mod X;) but not generate.
207/// These are hand-written modules imported by the generated lib.rs.
208#[derive(Debug, Clone, Default, Serialize, Deserialize)]
209pub struct CustomModulesConfig {
210    #[serde(default)]
211    pub python: Vec<String>,
212    #[serde(default)]
213    pub node: Vec<String>,
214    #[serde(default)]
215    pub ruby: Vec<String>,
216    #[serde(default)]
217    pub php: Vec<String>,
218    #[serde(default)]
219    pub elixir: Vec<String>,
220    #[serde(default)]
221    pub wasm: Vec<String>,
222    #[serde(default)]
223    pub ffi: Vec<String>,
224    #[serde(default)]
225    pub go: Vec<String>,
226    #[serde(default)]
227    pub java: Vec<String>,
228    #[serde(default)]
229    pub csharp: Vec<String>,
230    #[serde(default)]
231    pub r: Vec<String>,
232}
233
234impl CustomModulesConfig {
235    pub fn for_language(&self, lang: Language) -> &[String] {
236        match lang {
237            Language::Python => &self.python,
238            Language::Node => &self.node,
239            Language::Ruby => &self.ruby,
240            Language::Php => &self.php,
241            Language::Elixir => &self.elixir,
242            Language::Wasm => &self.wasm,
243            Language::Ffi => &self.ffi,
244            Language::Go => &self.go,
245            Language::Java => &self.java,
246            Language::Csharp => &self.csharp,
247            Language::R => &self.r,
248            Language::Rust => &[], // Rust doesn't need custom modules (no binding crate)
249        }
250    }
251}
252
253/// Custom classes/functions from hand-written modules to register in module init.
254#[derive(Debug, Clone, Default, Serialize, Deserialize)]
255pub struct CustomRegistration {
256    #[serde(default)]
257    pub classes: Vec<String>,
258    #[serde(default)]
259    pub functions: Vec<String>,
260    #[serde(default)]
261    pub init_calls: Vec<String>,
262}
263
264/// Per-language custom registrations.
265#[derive(Debug, Clone, Default, Serialize, Deserialize)]
266pub struct CustomRegistrationsConfig {
267    #[serde(default)]
268    pub python: Option<CustomRegistration>,
269    #[serde(default)]
270    pub node: Option<CustomRegistration>,
271    #[serde(default)]
272    pub ruby: Option<CustomRegistration>,
273    #[serde(default)]
274    pub php: Option<CustomRegistration>,
275    #[serde(default)]
276    pub elixir: Option<CustomRegistration>,
277    #[serde(default)]
278    pub wasm: Option<CustomRegistration>,
279}
280
281impl CustomRegistrationsConfig {
282    pub fn for_language(&self, lang: Language) -> Option<&CustomRegistration> {
283        match lang {
284            Language::Python => self.python.as_ref(),
285            Language::Node => self.node.as_ref(),
286            Language::Ruby => self.ruby.as_ref(),
287            Language::Php => self.php.as_ref(),
288            Language::Elixir => self.elixir.as_ref(),
289            Language::Wasm => self.wasm.as_ref(),
290            _ => None,
291        }
292    }
293}