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