# Elm Rust Binding
This crate offers a way to conveniently call an Elm function from Rust.
The main motivation here is for testing purposes:
- You have some logic in your Elm frontend that cannot be moved to the backend (because e.g. it is called in a hot loop)
- You have related logic in your Rust backend
Then you can call your Elm code in a Rust test with this crate to verify the two implementations are in sync.
The performance this crate offers is NOT optimal - do not use this for Interop in production code.
## Example
### Rust side
```rust
use elm_rust_binding::{ElmRoot, Result};
#[test]
fn call_elm() -> Result<()> {
let mut elm_root = ElmRoot::new("../frontend/src")?;
let mut square_fn = elm_root.prepare("Math.square")?;
let squared = square_fn.call(4)?;
assert_eq!(squared, 16);
Ok(())
}
```
### Elm side
```elm
-- In /frontend/src/Math.elm
module Math exposing (square)
square : Int -> Int
square n = n * n
```
Note that you can call the function multiple times, which will improve performance over creating a new `ElmRoot` and `ElmFunctionHandle`.
This is especially useful for fuzz/property-based testing
## Implementation Details
How does this work under the hood? It essentially boils down to 6 steps:
1. Infer the Elm input and output types based on the Rust type annotations (i32 -> Int, bool -> Bool, etc.).
2. Generate an .elm file with a `Platform.worker` main function. It will accept the input type over its flags and return the output type via a port. Internally it will call the specified function by importing it.
3. Invoke the Elm compiler on the generated file, producing a .js file.
4. Make the produced .js file ESM-compatible.
5. Load the module into a Deno runtime.
6. Initialize the Elm application every time `.call` is invoked by passing the input argument as flags and getting the output via `.subscribe`.
The generated files are removed automatically and are postfixed with a UUID to prevent different invocations messing with each other.
If you call `.debug()` on the `ElmRoot`, the files are not removed to help debugging issues.