1pub mod c;
4pub mod csharp;
5pub mod elixir;
6pub mod go;
7pub mod java;
8pub mod php;
9pub mod python;
10pub mod r;
11pub mod ruby;
12pub mod rust;
13pub mod typescript;
14pub mod wasm;
15
16use crate::config::E2eConfig;
17use crate::fixture::FixtureGroup;
18use alef_core::backend::GeneratedFile;
19use alef_core::config::AlefConfig;
20use anyhow::Result;
21
22pub(crate) fn normalize_json_keys_to_snake_case(value: &serde_json::Value) -> serde_json::Value {
27 use heck::ToSnakeCase;
28 match value {
29 serde_json::Value::Object(obj) => {
30 let new_obj: serde_json::Map<String, serde_json::Value> = obj
31 .iter()
32 .map(|(k, v)| (k.to_snake_case(), normalize_json_keys_to_snake_case(v)))
33 .collect();
34 serde_json::Value::Object(new_obj)
35 }
36 serde_json::Value::Array(arr) => {
37 serde_json::Value::Array(arr.iter().map(normalize_json_keys_to_snake_case).collect())
38 }
39 other => other.clone(),
40 }
41}
42
43pub trait E2eCodegen: Send + Sync {
45 fn generate(
47 &self,
48 groups: &[FixtureGroup],
49 e2e_config: &E2eConfig,
50 alef_config: &AlefConfig,
51 ) -> Result<Vec<GeneratedFile>>;
52
53 fn language_name(&self) -> &'static str;
55}
56
57pub fn all_generators() -> Vec<Box<dyn E2eCodegen>> {
59 vec![
60 Box::new(rust::RustE2eCodegen),
61 Box::new(python::PythonE2eCodegen),
62 Box::new(typescript::TypeScriptCodegen),
63 Box::new(go::GoCodegen),
64 Box::new(java::JavaCodegen),
65 Box::new(csharp::CSharpCodegen),
66 Box::new(php::PhpCodegen),
67 Box::new(ruby::RubyCodegen),
68 Box::new(elixir::ElixirCodegen),
69 Box::new(r::RCodegen),
70 Box::new(wasm::WasmCodegen),
71 Box::new(c::CCodegen),
72 ]
73}
74
75pub fn generators_for(languages: &[String]) -> Vec<Box<dyn E2eCodegen>> {
77 all_generators()
78 .into_iter()
79 .filter(|g| languages.iter().any(|l| l == g.language_name()))
80 .collect()
81}