pub mod brew;
pub mod c;
pub mod client;
pub mod csharp;
pub mod dart;
pub mod elixir;
pub mod gleam;
pub mod go;
pub mod java;
pub mod kotlin;
pub mod php;
pub mod python;
pub mod r;
pub mod ruby;
pub mod rust;
pub mod swift;
pub mod typescript;
pub mod wasm;
pub mod zig;
use crate::config::E2eConfig;
use crate::fixture::FixtureGroup;
use alef_core::backend::GeneratedFile;
use alef_core::config::AlefConfig;
use anyhow::Result;
pub(crate) fn normalize_json_keys_to_snake_case(value: &serde_json::Value) -> serde_json::Value {
use heck::ToSnakeCase;
match value {
serde_json::Value::Object(obj) => {
let new_obj: serde_json::Map<String, serde_json::Value> = obj
.iter()
.map(|(k, v)| (k.to_snake_case(), normalize_json_keys_to_snake_case(v)))
.collect();
serde_json::Value::Object(new_obj)
}
serde_json::Value::Array(arr) => {
serde_json::Value::Array(arr.iter().map(normalize_json_keys_to_snake_case).collect())
}
other => other.clone(),
}
}
pub trait E2eCodegen: Send + Sync {
fn generate(
&self,
groups: &[FixtureGroup],
e2e_config: &E2eConfig,
alef_config: &AlefConfig,
) -> Result<Vec<GeneratedFile>>;
fn language_name(&self) -> &'static str;
}
pub fn all_generators() -> Vec<Box<dyn E2eCodegen>> {
vec![
Box::new(rust::RustE2eCodegen),
Box::new(python::PythonE2eCodegen),
Box::new(typescript::TypeScriptCodegen),
Box::new(go::GoCodegen),
Box::new(java::JavaCodegen),
Box::new(kotlin::KotlinE2eCodegen),
Box::new(csharp::CSharpCodegen),
Box::new(php::PhpCodegen),
Box::new(ruby::RubyCodegen),
Box::new(elixir::ElixirCodegen),
Box::new(gleam::GleamE2eCodegen),
Box::new(r::RCodegen),
Box::new(wasm::WasmCodegen),
Box::new(c::CCodegen),
Box::new(zig::ZigE2eCodegen),
Box::new(dart::DartE2eCodegen),
Box::new(swift::SwiftE2eCodegen),
Box::new(brew::BrewCodegen),
]
}
pub fn generators_for(languages: &[String]) -> Vec<Box<dyn E2eCodegen>> {
all_generators()
.into_iter()
.filter(|g| languages.iter().any(|l| l == g.language_name()))
.collect()
}
pub(crate) fn resolve_field<'a>(input: &'a serde_json::Value, field_path: &str) -> &'a serde_json::Value {
let path = field_path.strip_prefix("input.").unwrap_or(field_path);
let mut current = input;
for part in path.split('.') {
current = current.get(part).unwrap_or(&serde_json::Value::Null);
}
current
}