use super::defaults::*;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RouteCallForm {
Direct,
Decorator,
Block,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct HarnessOverride {
#[serde(default)]
pub register_method: Option<String>,
#[serde(default)]
pub app_class: Option<String>,
#[serde(default)]
pub body_schema_setter: Option<String>,
#[serde(default)]
pub method_enum: Option<String>,
#[serde(default)]
pub run_method: Option<String>,
#[serde(default)]
pub imports: Option<Vec<String>>,
#[serde(default)]
pub server_config_factory: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct HarnessConfig {
#[serde(default)]
pub imports: Vec<String>,
#[serde(default)]
pub app_class: Option<String>,
#[serde(default)]
pub register_method: Option<String>,
#[serde(default)]
pub body_schema_setter: Option<String>,
#[serde(default)]
pub route_builder: Option<String>,
#[serde(default)]
pub method_enum: Option<String>,
#[serde(default)]
pub run_method: Option<String>,
#[serde(default = "default_response_body_field")]
pub response_body_field: String,
#[serde(default = "default_harness_host")]
pub host: String,
#[serde(default = "default_harness_port")]
pub port: u16,
#[serde(default)]
pub overrides: HashMap<String, HarnessOverride>,
}
impl Default for HarnessConfig {
fn default() -> Self {
Self {
imports: Vec::new(),
app_class: None,
register_method: None,
body_schema_setter: None,
route_builder: None,
method_enum: None,
run_method: None,
response_body_field: default_response_body_field(),
host: default_harness_host(),
port: default_harness_port(),
overrides: HashMap::new(),
}
}
}
impl HarnessConfig {
pub fn register_method_for_lang(&self, lang: &str) -> Option<String> {
self.overrides
.get(lang)
.and_then(|o| o.register_method.clone())
.or_else(|| self.register_method.clone())
}
pub fn run_method_for_lang(&self, lang: &str) -> Option<String> {
self.overrides
.get(lang)
.and_then(|o| o.run_method.clone())
.or_else(|| self.run_method.clone())
}
pub fn app_class_for_lang(&self, lang: &str) -> Option<String> {
self.overrides
.get(lang)
.and_then(|o| o.app_class.clone())
.or_else(|| self.app_class.clone())
}
pub fn imports_for_lang(&self, lang: &str) -> Vec<String> {
self.overrides
.get(lang)
.and_then(|o| o.imports.clone())
.unwrap_or_else(|| self.imports.clone())
}
pub fn server_config_factory_for_lang(&self, lang: &str) -> String {
self.overrides
.get(lang)
.and_then(|o| o.server_config_factory.clone())
.unwrap_or_else(|| match lang {
"node" => "serverConfigDefault()".to_string(),
"wasm" => "new WasmServerConfig()".to_string(),
_ => "new ServerConfig()".to_string(),
})
}
pub fn server_config_factory_import_for_lang(&self, lang: &str) -> Option<String> {
match lang {
"node" => Some("serverConfigDefault".to_string()),
"wasm" => Some("WasmServerConfig".to_string()),
_ => None,
}
}
pub fn harness_route_call_form_for_lang(&self, lang: &str) -> RouteCallForm {
match lang {
"python" => RouteCallForm::Decorator,
"ruby" => RouteCallForm::Block,
_ => RouteCallForm::Direct,
}
}
pub fn import_style_for_lang(&self, lang: &str) -> &'static str {
match lang {
"wasm" => "named",
_ => "default",
}
}
pub fn register_method_idiomatic(&self, lang: &str) -> Option<String> {
self.register_method_for_lang(lang)
.map(|name| idiomatic_identifier(&name, lang))
}
}
fn idiomatic_identifier(name: &str, lang: &str) -> String {
use heck::{ToLowerCamelCase, ToUpperCamelCase};
match lang {
"python" | "ruby" | "elixir" | "rust" | "php" => name.to_string(),
"typescript" | "node" | "wasm" | "javascript" | "dart" | "swift" | "kotlin" | "kotlin-android" | "java" => {
name.to_lower_camel_case()
}
"csharp" | "go" => name.to_upper_camel_case(),
_ => name.to_string(),
}
}