1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
//! Per-language spellings of a public host identifier, and the language-specific initialism
//! policy each one applies.
//!
//! The mechanical transforms these compose live in [`super::case`]; what belongs here is the
//! per-language *choice* — Go uppercasing `URL`, C# preferring `Json`, and so on. ~keep
use ;
use public_type_name;
use crateLanguage;
use ;
use HashSet;
/// Convert a Rust snake_case name to the target language convention.
/// Convert a Rust snake_case name to Node.js/TypeScript lowerCamelCase convention.
/// Public TypeScript type name for a NAPI-RS binding's `.d.ts`, for both a type's own
/// declaration (`export interface Foo`) and every reference to it elsewhere in the file
/// (a field type, a param type, a return type).
///
/// The compiled Rust side wraps `Foo` as a `Js`-prefixed struct (`JsFoo`) and remaps it back to
/// `Foo` at the JS boundary via `#[napi(js_name = "Foo")]`, so the `.d.ts` — which describes the
/// JS boundary, not the Rust struct — must use the identity name everywhere. Both the emitter's
/// declaration site and its reference site (`TypeRef::Named`) call this one function so they
/// cannot independently decide whether to keep the `Js` prefix. ~keep
/// Convert a Rust snake_case name to Ruby snake_case convention.
/// Convert a Rust snake_case name to PHP lowerCamelCase convention.
/// Convert a Rust snake_case name to Elixir snake_case convention.
/// Well-known initialisms that must be fully uppercased per Go naming conventions.
/// See: https://go.dev/wiki/CodeReviewComments#initialisms
const INITIALISMS: & = &;
/// Initialisms preserved in C# PascalCase. Microsoft's framework design guidelines
/// recommend `Json`/`Http`/`Url` rather than `JSON`/`HTTP`/`URL` (3+ letter
/// initialisms use PascalCase, 2-letter ones use all-caps). This list intentionally
/// excludes generic acronyms so they round-trip cleanly through heck's PascalCase
/// (matching alef's hardcoded helper names like `{Type}ToJson`/`{Type}FromJson`),
/// while still preserving product names like `GraphQL` that heck would mangle.
const CSHARP_INITIALISMS: & = &;
/// Apply Go initialism uppercasing to a PascalCase name.
///
/// Scans word boundaries in the PascalCase string and replaces any run of
/// characters that matches a known initialism (case-insensitively) with the
/// all-caps form. For example `ImageUrl` becomes `ImageURL` and `UserId`
/// becomes `UserID`.
/// Convert a Rust snake_case name to Go PascalCase convention with acronym uppercasing.
/// Convert a Rust free-function name to its Go wrapper identifier, disambiguating it from a
/// generated Go type of the same name.
///
/// A Rust crate can expose both a free function (e.g. `model_info`) and a struct (e.g.
/// `ModelInfo`) that map to the same Go PascalCase identifier, which the Go compiler rejects as
/// a redeclaration. Go struct/opaque/enum type names are never disambiguated (types are the
/// canonical identifier host consumers reach for), so on collision the function is renamed by
/// prefixing `Get`. `reserved_type_names` must contain every Go type identifier the backend will
/// emit (already passed through [`go_type_name`]).
/// Apply Go acronym uppercasing to a name that is already in PascalCase (e.g. an IR type name).
///
/// IR type names come directly from Rust PascalCase (e.g. `ImageUrl`, `JsonSchemaFormat`).
/// This function uppercases known acronym segments so they conform to Go naming conventions
/// (e.g. `ImageUrl` → `ImageURL`, `JsonSchemaFormat` → `JSONSchemaFormat`).
/// Convert a Rust snake_case parameter/variable name to Go lowerCamelCase with acronym uppercasing.
///
/// Go naming conventions require that acronyms in identifiers be fully uppercased.
/// `to_lower_camel_case` alone converts `base_url` → `baseUrl`, but Go wants `baseURL`.
/// This function converts via PascalCase (which applies acronym uppercasing) then lowercases
/// the first "word" (the initial run of uppercase letters treated as a unit) while preserving
/// the case of subsequent words/acronyms:
/// - `base_url` → `BaseURL` → `baseURL`
/// - `api_key` → `APIKey` → `apiKey`
/// - `user_id` → `UserID` → `userID`
/// - `json` → `JSON` → `json`
///
/// A parameter literally named `result` is renamed to `resultArg`. The Go return-marshalling
/// templates (`var_decl_slice`, `var_decl_type`, `result_json_unmarshal`, …) declare a hard-coded
/// local named `result` to hold the unmarshalled return value, so a parameter of the same name
/// would collide (`result redeclared`). `resultArg` is the only reserved rename needed because it is
/// the sole identifier the generated function bodies hard-code as a local.
/// Derive the Go package name from the last segment of a Go module path (fallback for when
/// `[go] package_name` is unset; prefer `ResolvedCrateConfig::go_package_name`).
/// Derive the Go-exported error type name for a Rust error type: strips a leading
/// case-insensitive match of the Go package name to avoid revive's stutter lint, e.g.
/// `("SampleError", "sample")` -> `"Error"`. Every caller that names the Go error type
/// (`gen_go_error_struct`, the e2e/docs snippet generator) must go through this, not re-derive
/// the rule, so they can't drift from what the Go backend emits.
/// Convert a Rust snake_case name to Java lowerCamelCase convention.
/// Convert a Rust snake_case name to C# PascalCase convention with initialism uppercasing.
///
/// Converts snake_case to PascalCase via `heck` and then restores C#-preserved initialisms.
/// The C# list is intentionally narrow (Microsoft's framework design guidelines prefer
/// `Json`/`Http`/`Url` over `JSON`/`HTTP`/`URL`), so only product names like `GraphQL`
/// and short 2-letter abbreviations get all-caps. This keeps method names like
/// `to_json` → `ToJson` in lockstep with alef's hardcoded `{Type}ToJson` /
/// `{Type}FromJson` helper declarations.
/// Derive the C# wrapper class name emitted by [`crate::backends::csharp::CsharpBackend`].
///
/// Converts the crate name to PascalCase, strips the Rust binding crate suffix "-rs",
/// and appends the idiomatic C# "Converter" suffix. For example:
/// - `sample-parser-rs` -> `SampleParser` -> `SampleParserConverter`
/// - `document_tools` -> `DocumentTools` -> `DocumentToolsConverter`
///
/// The README generator uses this helper so the generated C# usage example references
/// the same class name that the bindings actually emit.
/// Derive the Kotlin Android wrapper object name emitted by the `KotlinAndroidBackend`.
///
/// Converts the crate name to PascalCase and strips the Rust binding crate
/// suffix "-rs". The bare PascalCase name keeps the call site idiomatic
/// (`SampleParser.extractFile(...)` rather than `SampleParserConverter.extractFile(...)`)
/// and matches the bridge object emitted at `<Crate>Bridge` by
/// `crate::core::jni::bridge_class_name`. For example:
/// - `sample-parser-rs` -> `SampleParser`
/// - `document_tools` -> `DocumentTools`
/// Apply C# initialism handling to a name that is already in PascalCase (e.g. an IR type name).
///
/// IR type names come directly from Rust PascalCase (e.g. `GraphQLRouteConfig`, `HttpStatus`).
/// When such names have been processed by `heck::ToPascalCase` they may lose initialism
/// capitalisation for the names we explicitly preserve (e.g. `GraphQLRouteConfig` →
/// `GraphQlRouteConfig`). This function restores them.
///
/// Examples:
/// - `GraphQlRouteConfig` → `GraphQLRouteConfig`
/// - `GraphQLRouteConfig` → `GraphQLRouteConfig` (idempotent)
/// - `HttpStatus` → `HttpStatus` (left alone — `Http` not in `CSHARP_INITIALISMS`)