Skip to main content

alef_core/config/resolved/
naming.rs

1//! Language-specific naming methods for `ResolvedCrateConfig`.
2
3use super::ResolvedCrateConfig;
4
5impl ResolvedCrateConfig {
6    /// Get the Python module name.
7    pub fn python_module_name(&self) -> String {
8        self.python
9            .as_ref()
10            .and_then(|p| p.module_name.as_ref())
11            .cloned()
12            .unwrap_or_else(|| format!("_{}", self.name.replace('-', "_")))
13    }
14
15    /// Get the Node package name.
16    pub fn node_package_name(&self) -> String {
17        self.node
18            .as_ref()
19            .and_then(|n| n.package_name.as_ref())
20            .cloned()
21            .unwrap_or_else(|| self.name.clone())
22    }
23
24    /// Get the Ruby gem name.
25    pub fn ruby_gem_name(&self) -> String {
26        self.ruby
27            .as_ref()
28            .and_then(|r| r.gem_name.as_ref())
29            .cloned()
30            .unwrap_or_else(|| self.name.replace('-', "_"))
31    }
32
33    /// Get the PHP extension name.
34    pub fn php_extension_name(&self) -> String {
35        self.php
36            .as_ref()
37            .and_then(|p| p.extension_name.as_ref())
38            .cloned()
39            .unwrap_or_else(|| self.name.replace('-', "_"))
40    }
41
42    /// Get the PHP binding Cargo crate name (used for deriving the shared library filename).
43    pub fn php_cargo_crate_name(&self) -> Option<&str> {
44        self.php.as_ref().and_then(|p| p.cargo_crate_name.as_deref())
45    }
46
47    /// Get the Elixir app name.
48    pub fn elixir_app_name(&self) -> String {
49        self.elixir
50            .as_ref()
51            .and_then(|e| e.app_name.as_ref())
52            .cloned()
53            .unwrap_or_else(|| self.name.replace('-', "_"))
54    }
55
56    /// Get the Zig module name.
57    pub fn zig_module_name(&self) -> String {
58        self.zig
59            .as_ref()
60            .and_then(|z| z.module_name.as_ref())
61            .cloned()
62            .unwrap_or_else(|| self.name.replace('-', "_"))
63    }
64
65    /// Get the Dart pubspec package name.
66    ///
67    /// Returns `[dart] pubspec_name` if set, otherwise derives a snake_case
68    /// name from the crate name by replacing hyphens with underscores.
69    pub fn dart_pubspec_name(&self) -> String {
70        self.dart
71            .as_ref()
72            .and_then(|d| d.pubspec_name.as_ref())
73            .cloned()
74            .unwrap_or_else(|| self.name.replace('-', "_"))
75    }
76
77    /// Get the Swift module name.
78    ///
79    /// Returns `[swift] module_name` if configured, otherwise derives a PascalCase
80    /// name from the crate name (e.g. `"my-lib"` → `"MyLib"`).
81    pub fn swift_module(&self) -> String {
82        self.swift
83            .as_ref()
84            .and_then(|s| s.module_name.as_ref())
85            .cloned()
86            .unwrap_or_else(|| {
87                use heck::ToUpperCamelCase;
88                self.name.to_upper_camel_case()
89            })
90    }
91
92    /// Get the R package name.
93    pub fn r_package_name(&self) -> String {
94        self.r
95            .as_ref()
96            .and_then(|r| r.package_name.as_ref())
97            .cloned()
98            .unwrap_or_else(|| self.name.clone())
99    }
100
101    /// Get the WASM type name prefix (e.g. "Wasm" produces `WasmConversionOptions`).
102    /// Defaults to `"Wasm"`.
103    pub fn wasm_type_prefix(&self) -> String {
104        self.wasm
105            .as_ref()
106            .and_then(|w| w.type_prefix.as_ref())
107            .cloned()
108            .unwrap_or_else(|| "Wasm".to_string())
109    }
110
111    /// Get the Node/NAPI type name prefix (e.g. "Js" produces `JsConversionOptions`).
112    /// Defaults to `"Js"`.
113    pub fn node_type_prefix(&self) -> String {
114        self.node
115            .as_ref()
116            .and_then(|n| n.type_prefix.as_ref())
117            .cloned()
118            .unwrap_or_else(|| "Js".to_string())
119    }
120}
121
122#[cfg(test)]
123mod tests {
124    use crate::config::new_config::NewAlefConfig;
125
126    fn resolved_one(toml: &str) -> super::super::ResolvedCrateConfig {
127        let cfg: NewAlefConfig = toml::from_str(toml).unwrap();
128        cfg.resolve().unwrap().remove(0)
129    }
130
131    fn minimal() -> super::super::ResolvedCrateConfig {
132        resolved_one(
133            r#"
134[workspace]
135languages = ["python", "node"]
136
137[[crates]]
138name = "test-lib"
139sources = ["src/lib.rs"]
140"#,
141        )
142    }
143
144    #[test]
145    fn python_module_name_defaults_to_underscore_prefix() {
146        let r = minimal();
147        assert_eq!(r.python_module_name(), "_test_lib");
148    }
149
150    #[test]
151    fn python_module_name_explicit_override() {
152        let r = resolved_one(
153            r#"
154[workspace]
155languages = ["python"]
156
157[[crates]]
158name = "test-lib"
159sources = ["src/lib.rs"]
160
161[crates.python]
162module_name = "mymod"
163"#,
164        );
165        assert_eq!(r.python_module_name(), "mymod");
166    }
167
168    #[test]
169    fn node_package_name_defaults_to_crate_name() {
170        let r = minimal();
171        assert_eq!(r.node_package_name(), "test-lib");
172    }
173
174    #[test]
175    fn ruby_gem_name_replaces_hyphens() {
176        let r = minimal();
177        assert_eq!(r.ruby_gem_name(), "test_lib");
178    }
179
180    #[test]
181    fn php_extension_name_replaces_hyphens() {
182        let r = minimal();
183        assert_eq!(r.php_extension_name(), "test_lib");
184    }
185
186    #[test]
187    fn elixir_app_name_replaces_hyphens() {
188        let r = minimal();
189        assert_eq!(r.elixir_app_name(), "test_lib");
190    }
191
192    #[test]
193    fn zig_module_name_replaces_hyphens() {
194        let r = minimal();
195        assert_eq!(r.zig_module_name(), "test_lib");
196    }
197
198    #[test]
199    fn dart_pubspec_name_replaces_hyphens() {
200        let r = minimal();
201        assert_eq!(r.dart_pubspec_name(), "test_lib");
202    }
203
204    #[test]
205    fn swift_module_is_pascal_case() {
206        let r = minimal();
207        assert_eq!(r.swift_module(), "TestLib");
208    }
209
210    #[test]
211    fn r_package_name_defaults_to_crate_name() {
212        let r = minimal();
213        assert_eq!(r.r_package_name(), "test-lib");
214    }
215
216    #[test]
217    fn wasm_type_prefix_defaults_to_wasm() {
218        let r = minimal();
219        assert_eq!(r.wasm_type_prefix(), "Wasm");
220    }
221
222    #[test]
223    fn node_type_prefix_defaults_to_js() {
224        let r = minimal();
225        assert_eq!(r.node_type_prefix(), "Js");
226    }
227}