camel_cli/template/
processor.rs1use super::TemplateFile;
2
3pub fn processor_files(plugin_name: &str) -> Vec<TemplateFile> {
4 vec![
5 TemplateFile {
6 path: "Cargo.toml".to_string(),
7 content: cargo_toml(plugin_name),
8 },
9 TemplateFile {
10 path: "src/lib.rs".to_string(),
11 content: lib_rs().to_string(),
12 },
13 TemplateFile {
14 path: "Camel.plugin.toml".to_string(),
15 content: plugin_toml(plugin_name),
16 },
17 TemplateFile {
18 path: "README.md".to_string(),
19 content: readme_md(plugin_name),
20 },
21 TemplateFile {
22 path: ".gitignore".to_string(),
23 content: gitignore().to_string(),
24 },
25 TemplateFile {
26 path: "wit/camel-plugin.wit".to_string(),
27 content: camel_wit::PLUGIN_WIT.to_string(),
28 },
29 ]
30}
31
32fn cargo_toml(plugin_name: &str) -> String {
33 format!(
34 "[package]\nname = \"{plugin_name}\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[workspace]\n\n[lib]\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nwit-bindgen = \"0.57\"\n"
35 )
36}
37
38fn lib_rs() -> &'static str {
39 "use bindings::camel::plugin::types::{WasmBody, WasmError, WasmExchange};\nuse bindings::Guest;\n\n#[allow(clippy::too_many_arguments)]\nmod bindings {\n wit_bindgen::generate!({\n world: \"plugin\",\n path: \"../wit\",\n });\n}\n\nstruct Processor;\n\nimpl Guest for Processor {\n fn init() -> Result<(), String> {\n Ok(())\n }\n\n fn process(mut exchange: WasmExchange) -> Result<WasmExchange, WasmError> {\n exchange.input.body = match &exchange.input.body {\n WasmBody::Text(s) => WasmBody::Text(format!(\"processed: {s}\")),\n other => other.clone(),\n };\n Ok(exchange);\n }\n}\n\nbindings::export!(Processor with_types_in bindings);\n"
40}
41
42fn plugin_toml(plugin_name: &str) -> String {
43 format!(
44 "name = \"{plugin_name}\"\nversion = \"0.1.0\"\ntype = \"processor\"\nentry = \"{plugin_name}.wasm\"\n"
45 )
46}
47
48fn readme_md(plugin_name: &str) -> String {
49 format!(
50 "# {plugin_name}\n\nWASM processor plugin for Camel.\n\n## Build\n\n```bash\ncamel plugin build\n```\n\n## Files\n\n- `src/lib.rs`: plugin entrypoint implementing Guest\n- `Camel.plugin.toml`: plugin metadata for Camel\n"
51 )
52}
53
54fn gitignore() -> &'static str {
55 "target\n"
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn processor_files_contains_expected_paths() {
64 let files = processor_files("acme-processor");
65 let paths: Vec<&str> = files.iter().map(|f| f.path.as_str()).collect();
66
67 assert_eq!(files.len(), 6);
68 assert!(paths.contains(&"Cargo.toml"));
69 assert!(paths.contains(&"src/lib.rs"));
70 assert!(paths.contains(&"Camel.plugin.toml"));
71 assert!(paths.contains(&"README.md"));
72 assert!(paths.contains(&".gitignore"));
73 assert!(paths.contains(&"wit/camel-plugin.wit"));
74 }
75
76 #[test]
77 fn cargo_template_contains_cdylib() {
78 let cargo = cargo_toml("acme-processor");
79
80 assert!(cargo.contains("name = \"acme-processor\""));
81 assert!(cargo.contains("crate-type = [\"cdylib\"]"));
82 assert!(cargo.contains("wit-bindgen = \"0.57\""));
83 assert!(cargo.contains("[workspace]"));
84 assert!(!cargo.contains("camel-wasm-sdk"));
85 }
86
87 #[test]
88 fn lib_template_generates_bindings() {
89 let lib = lib_rs();
90
91 assert!(lib.contains("use bindings::Guest;"));
92 assert!(lib.contains("bindings::export!(Processor with_types_in bindings);"));
93 assert!(lib.contains("impl Guest for Processor"));
94 assert!(lib.contains("fn process("));
95 assert!(lib.contains("fn init()"));
96 assert!(lib.contains("wit_bindgen::generate!"));
97 assert!(lib.contains("mod bindings"));
98 }
99
100 #[test]
101 fn plugin_toml_contains_expected_keys() {
102 let plugin = plugin_toml("acme-processor");
103
104 assert!(plugin.contains("type = \"processor\""));
105 assert!(plugin.contains("entry = \"acme-processor.wasm\""));
106 }
107}