Skip to content

Instantly share code, notes, and snippets.

@jiraguha
Last active August 11, 2020 20:16
Show Gist options
  • Save jiraguha/901e016bb33691af531cf35f28c59bb6 to your computer and use it in GitHub Desktop.
Save jiraguha/901e016bb33691af531cf35f28c59bb6 to your computer and use it in GitHub Desktop.
Creating deno πŸ¦• Rust πŸ¦€ plugins usable in the JS/TS scripts [ short tuto]

Just exploring how deno Rust plugins can be used. !!! warning the feature is still instable!!!

Clone the deno source & go to deno/test_plugin

The repo is structure as following:

test_plugin
β”œβ”€β”€ Cargo.toml
β”œβ”€β”€ src
β”‚Β Β  └── lib.rs
└── tests
    β”œβ”€β”€ ...
    └── test.js

It is a rust repo.

In the rust

1- add deno_core & specify your project as a crate of type cdylib to make the lib dynamically available.

In the cargo manifest

[package]
name = "test_plugin"
...

[lib]
crate-type = ["cdylib"]

[dependencies]
...

deno_core = { path = "../core" }
...

2- wrap your custom lib functionalities in ops functions,

// in lib.rs
fn op_test_sync(
  _interface: &mut dyn Interface,
  zero_copy: &mut [ZeroCopyBuf],
) -> Op {
  
  ...
  
  Op::Sync(result_box)
}

3- register then inside the plugin container deno_plugin_init.

// in lib.rs
#[no_mangle]
pub fn deno_plugin_init(interface: &mut dyn Interface) {
  interface.register_op("testSync", op_test_sync);
  ...
}

4- build your lib with cargo : cargo build -p <name of the crate>

$ cargo build -p test_plugin --release

In js

5- open your lib with Deno.openPlugin. You had to specify the build target from (4)

// in test.js
 const rid = Deno.openPlugin(<path the .dylib>);

6 - get your functionality from ops with Deno.core.ops

// in test.js
const { testSync } = Deno.core.ops();

7 - dispatch call to your functionality with ops using Deno.core.dispatch

// in test.js
  const response = Deno.core.dispatch(
    testSync,
    new Uint8Array([116, 101, 115, 116]),
    new Uint8Array([49, 50, 51]),
    new Uint8Array([99, 98, 97]),
  );

async ops:

// in test.js
Deno.core.setAsyncHandler(testAsync, (response) => {
  console.log(`Plugin Async Response: ${textDecoder.decode(response)}`);
});

const response = Deno.core.dispatch(
    testAsync,
    new Uint8Array([116, 101, 115, 116]),
    new Uint8Array([49, 50, 51]),
  );
  

8 - close the plugin

// in test.js
  Deno.close(rid);

9 - run your script

$ deno run --allow-plugin --unstable tests/test.js release
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment