Skip to content

Commit

Permalink
Expanding explanation and example
Browse files Browse the repository at this point in the history
  • Loading branch information
ambiguousname authored Sep 30, 2024
1 parent f4e1c0a commit 1f481ae
Showing 1 changed file with 60 additions and 27 deletions.
87 changes: 60 additions & 27 deletions src/demo_gen/custom_functions.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,78 @@
# Making Custom Functions

Let's say you want to add your own custom demonstration functions for a given struct, without demo_gen automagically creating the content of JS functions for you.
## What is a custom function?

This is done with the `#[diplomat::demo(custom_func="filename.mjs")]` attribute, which can be added above any `struct` definition. demo_gen will search for files relative to `lib.rs`, and add the contents of `filename.mjs` to its output.
demo_gen tends towards automagical configuration. demo_gen will do its best to take Rust functions and convert them into JS output.

Then demo_gen will import the default export of `filename.mjs`, and append it to the list of [RenderInfo](https://github.com/rust-diplomat/diplomat/blob/main/docs/demo_gen.md#step-two-constructing-renderinfo) termini.
But there arise situations where we want to create our own custom Javascript functions to demonstrate our library's capabilities to the user, then add them to demo_gen's output. This may be the case if you want to demonstrate functionality that is more involved than demo_gen's automagical work.

Here's an example of what that looks like...
### Example
Let's look at the [quickstart](quickstart.md) repository for an example.

In rust:
We only have one function exposed: `get_add_str(left : u32, right: u32)`.

```rs
#[diplomat::bridge]
mod ffi {
#[diplomat::demo(custom_func="classname_demo.mjs")]
struct ClassName;
}
What if we have variables `a`, `b`, and `c`, and we want to show the user the results of calling:

`get_add_str(a, b)` and `get_add_str(b, c)`?

```
We can do this without adding a new binding, through the use of a custom Javascript function.

Then in `classname_demo.mjs`, we write:
## \#\[diplomat::demo(custom_func="...")\]

`#[diplomat::demo(custom_func="filename.mjs")]` can be added above any `struct` definition. demo_gen will search for files relative to `lib.rs`, and add the contents of `filename.mjs` to its output.

Then demo_gen will import the default export of `filename.mjs`, and append it to the list of [RenderInfo](https://github.com/rust-diplomat/diplomat/blob/main/docs/demo_gen.md#step-two-constructing-renderinfo) termini.

### Example
So, first we create a file called `adder_custom.mjs` in the same folder as `adder_bindings/src/lib.rs`:

```js
// adder_bindings/src/adder_custom.mjs
import { lib } from "./index.mjs";
export default {
"ClassName.SampleFunctionName": {
func: () => { alert("Hello world!"); },
funcName: "ClassName.SampleFunctionName",
parameters: [

]
},
"ClassName.OtherFunctionName": {
func: (a) => { prompt(`Testing!${a}`); },
funcName: "ClassName.OtherFunctionName",
"AddThreeVariables": {
func: (a, b, c) => { return lib.AddResult.getAddStr(a, b) + " and " + lib.AddResult.getAddStr(b, c); },
funcName: "Add a + b, b + c",
parameters: [
name: "Prompt Question",
type: "string"
{
name: "a",
type: "number"
},
{
name: "b",
type: "number"
},
{
name: "c",
type: "number"
}
]
}
};
}
```

Then we make sure to link `adder_custom.mjs` in `lib.rs`:

```rs
// adder_bindings/src/lib.rs
#[diplomat::bridge]
mod ffi {
use std::fmt::Write;

#[diplomat::opaque]
#[diplomat::rust_link(basic_adder, Mod)]
#[diplomat::demo(custom_func="adder_custom.mjs")]
pub struct AddResult;

impl AddResult {
pub fn get_add_str(left : u32, right : u32, write: &mut DiplomatWrite) {
write.write_str(&format!("{}", basic_adder::add(left, right))).unwrap();
write.flush();
}
}
}
```

And our exported object is then added to `RenderInfo`s list of render termini, and is evaluated by the renderer accordingly!
And our exported object is then added to `RenderInfo`s list of render termini, and is evaluated by the renderer accordingly!

If you [regenerate the bindings and start the web server](https://rust-diplomat.github.io/book/demo_gen/quickstart.html#getting-started), you should see `Add a + b, b + c` in the list of functions.

0 comments on commit 1f481ae

Please sign in to comment.