D
Deno

help

How to send an enum value from Rust to Deno

Ffuriouzz1/31/2024
Hello there 👋 I am quite a beginner to FFI and I am not sure which resources to read to learn more about it in Rust. My problem: I got two enums MyEvent and MySubEvent.
#[repr(C)]
pub enum MySubEvent {
X,
Y(f64),
}

#[repr(C)]
pub enum MyEvent {
Event(f64, f64),
SubEvent(MySubEvent),
Nothing,
}
#[repr(C)]
pub enum MySubEvent {
X,
Y(f64),
}

#[repr(C)]
pub enum MyEvent {
Event(f64, f64),
SubEvent(MySubEvent),
Nothing,
}
I want to emit these events to callback function declared in Deno side
#[no_mangle]
pub extern "C" fn run_event_loop(func: Option<extern "C" fn(MyEvent)>) {
let callback = func.unwrap();
callback(MyEvent::Event(0., 36.));
callback(MyEvent::SubEvent(MySubEvent::X));
callback(MyEvent::SubEvent(MySubEvent::Y(1.0)));
callback(MyEvent::Nothing);
}
#[no_mangle]
pub extern "C" fn run_event_loop(func: Option<extern "C" fn(MyEvent)>) {
let callback = func.unwrap();
callback(MyEvent::Event(0., 36.));
callback(MyEvent::SubEvent(MySubEvent::X));
callback(MyEvent::SubEvent(MySubEvent::Y(1.0)));
callback(MyEvent::Nothing);
}
I do not know how to recognize which event has been sent in Deno
const onEvent = new Deno.UnsafeCallback(
{
parameters: ["pointer"],
result: "void",
},
(e) => {
if (e === null) return;
const view = new Deno.UnsafePointerView(e);
const eventType = view.getUint32(); // Is it the right way to do it?
console.log(eventType);
}
);

const lib = Deno.dlopen("./target/debug/mylib.dylib", {
run_event_loop: { parameters: ["function"], result: "void" },
});

lib.symbols.run_event_loop(onEvent.pointer);
lib.close();
const onEvent = new Deno.UnsafeCallback(
{
parameters: ["pointer"],
result: "void",
},
(e) => {
if (e === null) return;
const view = new Deno.UnsafePointerView(e);
const eventType = view.getUint32(); // Is it the right way to do it?
console.log(eventType);
}
);

const lib = Deno.dlopen("./target/debug/mylib.dylib", {
run_event_loop: { parameters: ["function"], result: "void" },
});

lib.symbols.run_event_loop(onEvent.pointer);
lib.close();
DAHDeno AI Helper1/31/2024
Based on the documentation, Deno's FFI API currently supports a list of types that can be used to communicate between Deno and native libraries. However, complex types like enums are not directly supported. In your case, you are trying to pass an enum from Rust to Deno. This is not directly supported by Deno's FFI API. The types that are currently supported by Deno's FFI API are i8, u8, i16, u16, i32, u32, i64, u64, usize, f32, f64, void, pointer, buffer, function, and { struct: [...] }. One possible workaround could be to represent your enum as an integer or a struct in Rust and then pass it to Deno. On the Deno side, you can then interpret the received integer or struct as your enum. However, this approach requires you to manually manage the mapping between your enum and the integer or struct, and it may not work for complex enums. Here's an example of how you might do this:
#[repr(C)]
pub enum MyEvent {
Event = 1,
SubEvent = 2,
Nothing = 3,
}

#[no_mangle]
pub extern "C" fn run_event_loop(func: Option<extern "C" fn(u32)>) {
let callback = func.unwrap();
callback(MyEvent::Event as u32);
callback(MyEvent::SubEvent as u32);
callback(MyEvent::Nothing as u32);
}
#[repr(C)]
pub enum MyEvent {
Event = 1,
SubEvent = 2,
Nothing = 3,
}

#[no_mangle]
pub extern "C" fn run_event_loop(func: Option<extern "C" fn(u32)>) {
let callback = func.unwrap();
callback(MyEvent::Event as u32);
callback(MyEvent::SubEvent as u32);
callback(MyEvent::Nothing as u32);
}
And on the Deno side:
const onEvent = new Deno.UnsafeCallback(
{
parameters: ["u32"],
result: "void",
},
(eventType) => {
console.log(eventType);
}
);

const lib = Deno.dlopen("./target/debug/mylib.dylib", {
run_event_loop: { parameters: ["function"], result: "void" },
});

lib.symbols.run_event_loop(onEvent.pointer);
lib.close();
const onEvent = new Deno.UnsafeCallback(
{
parameters: ["u32"],
result: "void",
},
(eventType) => {
console.log(eventType);
}
);

const lib = Deno.dlopen("./target/debug/mylib.dylib", {
run_event_loop: { parameters: ["function"], result: "void" },
});

lib.symbols.run_event_loop(onEvent.pointer);
lib.close();
In this example, the Rust enum MyEvent is represented as an integer (u32), and this integer is passed to Deno through the FFI API. On the Deno side, the received integer
DAHDeno AI Helper1/31/2024
is then interpreted as the enum MyEvent. Please note that this is a workaround and may not work for complex enums or enums with
Ffuriouzz1/31/2024
Is it a possible to pass the event type with the event?
NNeTT1/31/2024
The easiest way would be passing around numbers but since you have different levels of info going around, maybe use serde?
Ffuriouzz1/31/2024
At the end, I want to use Event from winit. winit uses enums and subenums.

Looking for more? Join the community!

Recommended Posts
Dependency injection deno deployDoes anyone know a Decency Injection library or container that works on deno deploy?Fetch request from own server```js try { const response = await fetch('.../ping', { Service keep restartingTwo GitHub projects, prod and customer are created using Deno for data syncing. Both projects are hRun `nvm` using Deno.CommandHello, I am trying to run `nvm` from a Deno script using Deno.Command. ```ts new Deno.Command('nvmCreating custom GitHub Action using DenoHey, I am currently trying to develop my first own custom GitHub Action. I have some trouble settinghow to avoid deprecation warnings in compiled binaries```sh $ pkgx --version warning: Use of deprecated "Deno.stderr.rid" API. This API will be removed inDeno compile with "--no-terminal" don't workI'm trying to compile a very simple file named main.ts ```ts await Deno.writeTextFile('test.txt', 'Hdeno task start not runnning in Powershell.This is the link of the tutorial I am following https://github.com/googleanalytics/ga4-tutorials?tabDeployment ID not available after API deploymentHi - i'm calling the /deployments endpoint after creating a new project: ${API}/projects/${project.`Request` body reading functions: possible error types[This](https://docs.deno.com/runtime/manual/runtime/http_server_apis#inspecting-the-incoming-requestHow to call a JS function from Rust?Hi, I'd like to call a JS function from Rust but I can't seem to find an example that does so. I goView code in Subhosting projectHi there - i'm using the API to create a new project and deployment with Subhosting. Just wondering Stop deno deploy instanceHi everyone, I just deployed my first test deno project on deno deploy. Now I'm wondering how to stoHow can I flush a stream to a response?I'm trying to stream a response but it appears that data is only sent after either a newline is writ