1mod rust;
14mod c;
15mod cxx;
16mod objc;
17mod swift;
18mod go;
19mod js;
20mod python;
21mod ruby;
22mod java;
23mod csharp;
24mod haskell;
25
26use std::io;
27use std::rc::Rc;
28use std::cell::RefCell;
29use heck::{ SnakeCase, ShoutySnakeCase, MixedCase, CamelCase };
30use error::Result;
31use sqir::*;
32
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
36pub enum DatabaseEngine {
37 SQLite3,
39 MongoDB,
41 MariaDB,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
47pub enum Language {
48 Rust,
50 C,
52 CXX,
54 ObjectiveC,
56 Swift,
58 Go,
60 JavaScript,
62 Python,
64 Ruby,
66 Java,
68 CSharp,
70 Haskell,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
76pub enum DatabaseAccessMode {
77 Pod,
80 ActiveRecord,
83}
84
85impl Default for DatabaseAccessMode {
87 fn default() -> Self {
88 DatabaseAccessMode::Pod
89 }
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
97pub enum NameTransform {
98 Identity,
100 LowerSnakeCase,
102 UpperSnakeCase,
104 LowerCamelCase,
106 UpperCamelCase,
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
112pub struct CodegenParams {
113 pub database: DatabaseEngine,
115 pub language: Language,
117 pub database_access_mode: Option<DatabaseAccessMode>,
119 pub namespace: Option<String>,
123 pub type_name_transform: Option<NameTransform>,
125 pub field_name_transform: Option<NameTransform>,
127 pub variant_name_transform: Option<NameTransform>,
129 pub func_name_transform: Option<NameTransform>,
131 pub namespace_transform: Option<NameTransform>,
133}
134
135pub type WriterProvider = FnMut(&str) -> Result<Rc<RefCell<io::Write>>>;
144
145
146pub fn generate_dal(sqir: &Sqir, params: &CodegenParams, wp: &mut WriterProvider) -> Result<()> {
162 use self::Language::*;
163
164 match params.language {
165 Rust => rust ::generate_dal(sqir, params, wp),
166 C => c ::generate_dal(sqir, params, wp),
167 CXX => cxx ::generate_dal(sqir, params, wp),
168 ObjectiveC => objc ::generate_dal(sqir, params, wp),
169 Swift => swift ::generate_dal(sqir, params, wp),
170 Go => go ::generate_dal(sqir, params, wp),
171 JavaScript => js ::generate_dal(sqir, params, wp),
172 Python => python ::generate_dal(sqir, params, wp),
173 Ruby => ruby ::generate_dal(sqir, params, wp),
174 Java => java ::generate_dal(sqir, params, wp),
175 CSharp => csharp ::generate_dal(sqir, params, wp),
176 Haskell => haskell::generate_dal(sqir, params, wp),
177 }
178}
179
180fn transform_type_name(name: &str, params: &CodegenParams) -> String {
185 transform_name(
186 name,
187 params.type_name_transform,
188 params.language,
189 default_type_name_transform,
190 )
191}
192
193fn transform_field_name(name: &str, params: &CodegenParams) -> String {
194 transform_name(
195 name,
196 params.field_name_transform,
197 params.language,
198 default_field_name_transform,
199 )
200}
201
202fn transform_variant_name(name: &str, params: &CodegenParams) -> String {
203 transform_name(
204 name,
205 params.variant_name_transform,
206 params.language,
207 default_variant_name_transform,
208 )
209}
210
211fn transform_func_name(name: &str, params: &CodegenParams) -> String {
212 transform_name(
213 name,
214 params.func_name_transform,
215 params.language,
216 default_func_name_transform,
217 )
218}
219
220fn transform_namespace(name: &str, params: &CodegenParams) -> String {
221 transform_name(
222 name,
223 params.namespace_transform,
224 params.language,
225 default_namespace_transform,
226 )
227}
228
229fn transform_name<D>(
230 name: &str,
231 transform: Option<NameTransform>,
232 lang: Language,
233 default: D,
234) -> String
235 where D: FnOnce(Language) -> NameTransform {
236
237 use self::NameTransform::*;
238
239 match transform.unwrap_or_else(|| default(lang)) {
240 Identity => name.to_owned(),
241 LowerSnakeCase => name.to_snake_case(),
242 UpperSnakeCase => name.to_shouty_snake_case(),
243 LowerCamelCase => name.to_mixed_case(),
244 UpperCamelCase => name.to_camel_case(),
245 }
246}
247
248fn default_type_name_transform(lang: Language) -> NameTransform {
249 use self::Language::*;
250 use self::NameTransform::*;
251
252 match lang {
253 Rust => UpperCamelCase,
254 C => UpperCamelCase,
255 CXX => UpperCamelCase,
256 ObjectiveC => UpperCamelCase,
257 Swift => UpperCamelCase,
258 Go => UpperCamelCase,
259 JavaScript => UpperCamelCase,
260 Python => UpperCamelCase,
261 Ruby => UpperCamelCase,
262 Java => UpperCamelCase,
263 CSharp => UpperCamelCase,
264 Haskell => UpperCamelCase,
265 }
266}
267
268fn default_field_name_transform(lang: Language) -> NameTransform {
269 use self::Language::*;
270 use self::NameTransform::*;
271
272 match lang {
273 Rust => LowerSnakeCase,
274 C => LowerSnakeCase,
275 CXX => LowerSnakeCase,
276 ObjectiveC => LowerCamelCase,
277 Swift => LowerCamelCase,
278 Go => UpperCamelCase,
279 JavaScript => LowerCamelCase,
280 Python => LowerSnakeCase,
281 Ruby => LowerSnakeCase,
282 Java => LowerCamelCase,
283 CSharp => UpperCamelCase,
284 Haskell => LowerCamelCase,
285 }
286}
287
288fn default_variant_name_transform(lang: Language) -> NameTransform {
289 use self::Language::*;
290 use self::NameTransform::*;
291
292 match lang {
293 Rust => UpperCamelCase,
294 C => UpperCamelCase,
295 CXX => UpperCamelCase,
296 ObjectiveC => UpperCamelCase,
297 Swift => LowerCamelCase, Go => UpperCamelCase,
299 JavaScript => UpperCamelCase,
300 Python => UpperSnakeCase,
301 Ruby => UpperSnakeCase,
302 Java => UpperSnakeCase,
303 CSharp => UpperCamelCase,
304 Haskell => UpperCamelCase,
305 }
306}
307
308fn default_func_name_transform(lang: Language) -> NameTransform {
309 use self::Language::*;
310 use self::NameTransform::*;
311
312 match lang {
313 Rust => LowerSnakeCase,
314 C => LowerSnakeCase,
315 CXX => LowerSnakeCase,
316 ObjectiveC => LowerCamelCase,
317 Swift => LowerCamelCase,
318 Go => UpperCamelCase,
319 JavaScript => LowerCamelCase,
320 Python => LowerSnakeCase,
321 Ruby => LowerSnakeCase,
322 Java => LowerCamelCase,
323 CSharp => UpperCamelCase,
324 Haskell => LowerCamelCase,
325 }
326}
327
328fn default_namespace_transform(lang: Language) -> NameTransform {
329 use self::Language::*;
330 use self::NameTransform::*;
331
332 match lang {
334 Rust => Identity,
335 C => Identity,
336 CXX => Identity,
337 ObjectiveC => Identity,
338 Swift => Identity,
339 Go => Identity,
340 JavaScript => Identity,
341 Python => Identity,
342 Ruby => Identity,
343 Java => Identity,
344 CSharp => Identity,
345 Haskell => Identity,
346 }
347}