mod rust;
mod c;
mod cxx;
mod objc;
mod swift;
mod go;
mod js;
mod python;
mod ruby;
mod java;
mod csharp;
mod haskell;
use std::io;
use std::rc::Rc;
use std::cell::RefCell;
use heck::{ SnakeCase, ShoutySnakeCase, MixedCase, CamelCase };
use error::Result;
use sqir::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DatabaseEngine {
SQLite3,
MongoDB,
MariaDB,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Language {
Rust,
C,
CXX,
ObjectiveC,
Swift,
Go,
JavaScript,
Python,
Ruby,
Java,
CSharp,
Haskell,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DatabaseAccessMode {
Pod,
ActiveRecord,
}
impl Default for DatabaseAccessMode {
fn default() -> Self {
DatabaseAccessMode::Pod
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum NameTransform {
Identity,
LowerSnakeCase,
UpperSnakeCase,
LowerCamelCase,
UpperCamelCase,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CodegenParams {
pub database: DatabaseEngine,
pub language: Language,
pub database_access_mode: Option<DatabaseAccessMode>,
pub namespace: Option<String>,
pub type_name_transform: Option<NameTransform>,
pub field_name_transform: Option<NameTransform>,
pub variant_name_transform: Option<NameTransform>,
pub func_name_transform: Option<NameTransform>,
pub namespace_transform: Option<NameTransform>,
}
pub type WriterProvider = FnMut(&str) -> Result<Rc<RefCell<io::Write>>>;
pub fn generate_dal(sqir: &Sqir, params: &CodegenParams, wp: &mut WriterProvider) -> Result<()> {
use self::Language::*;
match params.language {
Rust => rust ::generate_dal(sqir, params, wp),
C => c ::generate_dal(sqir, params, wp),
CXX => cxx ::generate_dal(sqir, params, wp),
ObjectiveC => objc ::generate_dal(sqir, params, wp),
Swift => swift ::generate_dal(sqir, params, wp),
Go => go ::generate_dal(sqir, params, wp),
JavaScript => js ::generate_dal(sqir, params, wp),
Python => python ::generate_dal(sqir, params, wp),
Ruby => ruby ::generate_dal(sqir, params, wp),
Java => java ::generate_dal(sqir, params, wp),
CSharp => csharp ::generate_dal(sqir, params, wp),
Haskell => haskell::generate_dal(sqir, params, wp),
}
}
fn transform_type_name(name: &str, params: &CodegenParams) -> String {
transform_name(
name,
params.type_name_transform,
params.language,
default_type_name_transform,
)
}
fn transform_field_name(name: &str, params: &CodegenParams) -> String {
transform_name(
name,
params.field_name_transform,
params.language,
default_field_name_transform,
)
}
fn transform_variant_name(name: &str, params: &CodegenParams) -> String {
transform_name(
name,
params.variant_name_transform,
params.language,
default_variant_name_transform,
)
}
fn transform_func_name(name: &str, params: &CodegenParams) -> String {
transform_name(
name,
params.func_name_transform,
params.language,
default_func_name_transform,
)
}
fn transform_namespace(name: &str, params: &CodegenParams) -> String {
transform_name(
name,
params.namespace_transform,
params.language,
default_namespace_transform,
)
}
fn transform_name<D>(
name: &str,
transform: Option<NameTransform>,
lang: Language,
default: D,
) -> String
where D: FnOnce(Language) -> NameTransform {
use self::NameTransform::*;
match transform.unwrap_or_else(|| default(lang)) {
Identity => name.to_owned(),
LowerSnakeCase => name.to_snake_case(),
UpperSnakeCase => name.to_shouty_snake_case(),
LowerCamelCase => name.to_mixed_case(),
UpperCamelCase => name.to_camel_case(),
}
}
fn default_type_name_transform(lang: Language) -> NameTransform {
use self::Language::*;
use self::NameTransform::*;
match lang {
Rust => UpperCamelCase,
C => UpperCamelCase,
CXX => UpperCamelCase,
ObjectiveC => UpperCamelCase,
Swift => UpperCamelCase,
Go => UpperCamelCase,
JavaScript => UpperCamelCase,
Python => UpperCamelCase,
Ruby => UpperCamelCase,
Java => UpperCamelCase,
CSharp => UpperCamelCase,
Haskell => UpperCamelCase,
}
}
fn default_field_name_transform(lang: Language) -> NameTransform {
use self::Language::*;
use self::NameTransform::*;
match lang {
Rust => LowerSnakeCase,
C => LowerSnakeCase,
CXX => LowerSnakeCase,
ObjectiveC => LowerCamelCase,
Swift => LowerCamelCase,
Go => UpperCamelCase,
JavaScript => LowerCamelCase,
Python => LowerSnakeCase,
Ruby => LowerSnakeCase,
Java => LowerCamelCase,
CSharp => UpperCamelCase,
Haskell => LowerCamelCase,
}
}
fn default_variant_name_transform(lang: Language) -> NameTransform {
use self::Language::*;
use self::NameTransform::*;
match lang {
Rust => UpperCamelCase,
C => UpperCamelCase,
CXX => UpperCamelCase,
ObjectiveC => UpperCamelCase,
Swift => LowerCamelCase, Go => UpperCamelCase,
JavaScript => UpperCamelCase,
Python => UpperSnakeCase,
Ruby => UpperSnakeCase,
Java => UpperSnakeCase,
CSharp => UpperCamelCase,
Haskell => UpperCamelCase,
}
}
fn default_func_name_transform(lang: Language) -> NameTransform {
use self::Language::*;
use self::NameTransform::*;
match lang {
Rust => LowerSnakeCase,
C => LowerSnakeCase,
CXX => LowerSnakeCase,
ObjectiveC => LowerCamelCase,
Swift => LowerCamelCase,
Go => UpperCamelCase,
JavaScript => LowerCamelCase,
Python => LowerSnakeCase,
Ruby => LowerSnakeCase,
Java => LowerCamelCase,
CSharp => UpperCamelCase,
Haskell => LowerCamelCase,
}
}
fn default_namespace_transform(lang: Language) -> NameTransform {
use self::Language::*;
use self::NameTransform::*;
match lang {
Rust => Identity,
C => Identity,
CXX => Identity,
ObjectiveC => Identity,
Swift => Identity,
Go => Identity,
JavaScript => Identity,
Python => Identity,
Ruby => Identity,
Java => Identity,
CSharp => Identity,
Haskell => Identity,
}
}