You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This library can be used to write [Extism Plug-ins](https://extism.org/docs/concepts/plug-in) in Rust.
5
+
This library can be used to write
6
+
[Extism Plug-ins](https://extism.org/docs/concepts/plug-in) in Rust.
6
7
7
8
## Install
8
9
@@ -18,7 +19,9 @@ Add the library from [crates.io](https://crates.io/crates/extism-pdk).
18
19
cargo add extism-pdk
19
20
```
20
21
21
-
Change your `Cargo.toml` to set the crate-type to `cdylib` (this instructs the compiler to produce a dynamic library, which for our target will be a Wasm binary):
22
+
Change your `Cargo.toml` to set the crate-type to `cdylib` (this instructs the
23
+
compiler to produce a dynamic library, which for our target will be a Wasm
24
+
binary):
22
25
23
26
```toml
24
27
[lib]
@@ -27,7 +30,9 @@ crate_type = ["cdylib"]
27
30
28
31
### Rustup and wasm32-unknown-unknown installation
29
32
30
-
Our example below will use the `wasm32-unknown-unknown` target. If this is not installed you will need to do so before this example will build. The easiest way to do this is use [`rustup`](https://rustup.rs/).
33
+
Our example below will use the `wasm32-unknown-unknown` target. If this is not
34
+
installed you will need to do so before this example will build. The easiest way
35
+
to do this is use [`rustup`](https://rustup.rs/).
31
36
32
37
```bash
33
38
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
@@ -39,11 +44,15 @@ Once `rustup` is installed, add the `wasm32-unknown-unknown` target:
39
44
rustup target add wasm32-unknown-unknown
40
45
```
41
46
42
-
43
47
## Getting Started
44
48
45
-
The goal of writing an [Extism plug-in](https://extism.org/docs/concepts/plug-in) is to compile your Rust code to a Wasm module with exported functions that the host application can invoke. The first thing you should understand is creating an export. Let's write a simple program that exports a `greet` function which will take a name as a string and return a greeting string. For this, we use the `#[plugin_fn]` macro on our exported function:
46
-
49
+
The goal of writing an
50
+
[Extism plug-in](https://extism.org/docs/concepts/plug-in) is to compile your
51
+
Rust code to a Wasm module with exported functions that the host application can
52
+
invoke. The first thing you should understand is creating an export. Let's write
53
+
a simple program that exports a `greet` function which will take a name as a
54
+
string and return a greeting string. For this, we use the `#[plugin_fn]` macro
Since we don't need any system access for this, we can compile this to the lightweight `wasm32-unknown-unknown` target instead of using the `wasm32-wasi` target:
66
+
Since we don't need any system access for this, we can compile this to the
67
+
lightweight `wasm32-unknown-unknown` target instead of using the `wasm32-wasi`
68
+
target:
58
69
59
70
```bash
60
71
cargo build --target wasm32-unknown-unknown
61
72
```
62
73
63
74
> **Note**: You can also put a default target in `.cargo/config.toml`:
75
+
64
76
```toml
65
77
[build]
66
78
target = "wasm32-unknown-unknown"
67
79
```
68
80
69
-
This will put your compiled wasm in `target/wasm32-unknown-unknown/debug`.
70
-
We can now test it using the [Extism CLI](https://github.com/extism/cli)'s `run`
81
+
This will put your compiled wasm in `target/wasm32-unknown-unknown/debug`. We
82
+
can now test it using the [Extism CLI](https://github.com/extism/cli)'s `run`
Adding the [plugin_fn](https://docs.rs/extism-pdk/latest/extism_pdk/attr.plugin_fn.html) macro to your function does a couple things. It exposes your function as an export and it handles some of the lower level ABI details that allow you to declare your Wasm function as if it were a normal Rust function. Here are a few examples of exports you can define.
> **Note**: The [plugin_fn](https://docs.rs/extism-pdk/latest/extism_pdk/attr.plugin_fn.html) macro uses the [convert crate](https://github.com/extism/extism/tree/main/convert) to automatically convert and pass types across the guest / host boundary.
[plugin_fn](https://docs.rs/extism-pdk/latest/extism_pdk/attr.plugin_fn.html) is a nice macro abstraction but there may be times where you want more control. You can code directly to the raw ABI interface of export functions.
169
-
193
+
[plugin_fn](https://docs.rs/extism-pdk/latest/extism_pdk/attr.plugin_fn.html) is
194
+
a nice macro abstraction but there may be times where you want more control. You
195
+
can code directly to the raw ABI interface of export functions.
Variables are another key-value mechanism but it's a mutable data store that
204
232
will persist across function calls. These variables will persist as long as the
205
-
host has loaded and not freed the plug-in. You can use [var::get](https://docs.rs/extism-pdk/latest/extism_pdk/var/fn.get.html) and [var::set](https://docs.rs/extism-pdk/latest/extism_pdk/var/fn.set.html) to manipulate them.
233
+
host has loaded and not freed the plug-in. You can use
234
+
[var::get](https://docs.rs/extism-pdk/latest/extism_pdk/var/fn.get.html) and
235
+
[var::set](https://docs.rs/extism-pdk/latest/extism_pdk/var/fn.set.html) to
Because Wasm modules by default do not have access to the system, printing to stdout won't work (unless you use WASI). Extism provides some simple logging macros that allow you to use the host application to log without having to give the plug-in permission to make syscalls. The primary one is [log!](https://docs.rs/extism-pdk/latest/extism_pdk/macro.log.html) but we also have some convenience macros named by log level:
250
+
Because Wasm modules by default do not have access to the system, printing to
251
+
stdout won't work (unless you use WASI). Extism provides some simple logging
252
+
macros that allow you to use the host application to log without having to give
253
+
the plug-in permission to make syscalls. The primary one is
254
+
[log!](https://docs.rs/extism-pdk/latest/extism_pdk/macro.log.html) but we also
> *Note*: From the CLI you need to pass a level with `--log-level`. If you are running the plug-in in your own host using one of our SDKs, you need to make sure that you call `set_log_file` to `"stdout"` or some file location.
282
+
> _Note_: From the CLI you need to pass a level with `--log-level`. If you are
283
+
> running the plug-in in your own host using one of our SDKs, you need to make
284
+
> sure that you call `set_log_file` to `"stdout"` or some file location.
247
285
248
286
## HTTP
249
287
250
288
Sometimes it is useful to let a plug-in make HTTP calls.
251
289
252
-
> **Note**: See [HttpRequest](https://docs.rs/extism-pdk/latest/extism_pdk/struct.HttpRequest.html) docs for more info on the request and response types:
Like any other code module, Wasm not only let's you export functions to the outside world, you can
265
-
import them too. Host Functions allow a plug-in to import functions defined in the host. For example,
266
-
if you host application is written in Python, it can pass a Python function down to your Rust plug-in
267
-
where you can invoke it.
304
+
Like any other code module, Wasm not only let's you export functions to the
305
+
outside world, you can import them too. Host Functions allow a plug-in to import
306
+
functions defined in the host. For example, if you host application is written
307
+
in Python, it can pass a Python function down to your Rust plug-in where you can
308
+
invoke it.
268
309
269
-
This topic can get fairly complicated and we have not yet fully abstracted the Wasm knowledge you need
270
-
to do this correctly. So we recommend reading out [concept doc on Host Functions](https://extism.org/docs/concepts/host-functions) before you get started.
310
+
This topic can get fairly complicated and we have not yet fully abstracted the
311
+
Wasm knowledge you need to do this correctly. So we recommend reading out
312
+
[concept doc on Host Functions](https://extism.org/docs/concepts/host-functions)
313
+
before you get started.
271
314
272
315
### A Simple Example
273
316
274
-
Host functions have a similar interface as exports. You just need to declare them as `extern` on the top of your `lib.rs`. You only declare the interface as it is the host's responsibility to provide the implementation:
317
+
Host functions have a similar interface as exports. You just need to declare
318
+
them as `extern` on the top of your `lib.rs`. You only declare the interface as
319
+
it is the host's responsibility to provide the implementation:
275
320
276
321
```rust
277
322
#[host_fn]
@@ -280,20 +325,23 @@ extern "ExtismHost" {
280
325
}
281
326
```
282
327
283
-
> **Note**: Under the hood this macro turns this into an interface that passes a pointer as an argument
284
-
> and a pointer as a return. If you want to pass raw, dereferenced wasm values see the raw interface documentation below.
328
+
> **Note**: Under the hood this macro turns this into an interface that passes a
329
+
> pointer as an argument and a pointer as a return. If you want to pass raw,
330
+
> dereferenced wasm values see the raw interface documentation below.
285
331
286
-
To declare a host function in a specific namespace, pass the module name to the `host_fn` macro:
332
+
To declare a host function in a specific namespace, pass the module name to the
333
+
`host_fn` macro:
287
334
288
335
```rust
289
336
#[host_fn("extism:host/user")]
290
337
```
291
338
292
-
> **Note**: The types we accept here are the same as the exports as the interface also uses the [convert crate](https://docs.rs/extism-convert/latest/extism_convert/).
293
-
294
-
To call this function, we must use the `unsafe` keyword. Also note that it automatically wraps the
295
-
function return with a Result in case the call fails.
339
+
> **Note**: The types we accept here are the same as the exports as the
We can't really test this from the Extism CLI as something must provide the implementation. So let's
309
-
write out the Python side here. Check out the [docs for Host SDKs](https://extism.org/docs/concepts/host-sdk) to implement a host function in a language of your choice.
356
+
We can't really test this from the Extism CLI as something must provide the
357
+
implementation. So let's write out the Python side here. Check out the
358
+
[docs for Host SDKs](https://extism.org/docs/concepts/host-sdk) to implement a
0 commit comments