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