I've got an exported-to-NodeJS Rust function that does something. Now, I want to extract part of that function into its own function (creating a JS object), so that I can reuse that logic in another, new exporter-to-NodeJS Rust function. However, I'm having great troubles figuring out how to pass the Context into that sub-function in a way that Rust is happy with. So far, the best (as in, "causes the compiler to complain the least") solution I have is this:
fn encode_num(mut cx: FunctionContext) -> JsResult<JsObject> {
let input = cx.argument::<JsNumber>(0)?.value(&mut cx);
let output = OrePlaintext::<u64>::from(input).0;
plaintext_from_u64(&mut cx, output)
}
fn plaintext_from_u64<'a>(cx: &'a mut FunctionContext, n: u64) -> JsResult<'a, JsObject> {
let bytes = n.to_ne_bytes();
let mut buf = match cx.buffer(8) {
Ok(b) => b,
Err(e) => return cx.throw_error(format!("Failed to allocate buffer: {:?}", e))
};
cx.borrow_mut(&mut buf, |data| {
let slice = data.as_mut_slice::<u8>();
for i in 0..8 {
slice[i] = bytes[i];
};
});
let obj = cx.empty_object();
obj.set(&mut cx, "kind", cx.string("OrePlainText"))?;
obj.set(&mut cx, "buf", buf)?;
Ok(obj)
}
#[neon::main]
fn main(mut cx: ModuleContext) -> NeonResult<()> {
cx.export_function("encodeNumber", encode_num)?;
Ok(())
}
This fails to compile with the following errors:
error[E0277]: the trait bound `&'a mut CallContext<'_, neon::prelude::JsObject>: neon::context::Context<'_>` is not satisfied
--> native/lib.rs:120:9
|
120 | obj.set(&mut cx, "kind", cx.string("OrePlainText"))?;
| ^^^ the trait `neon::context::Context<'_>` is not implemented for `&'a mut CallContext<'_, neon::prelude::JsObject>`
|
= help: the following implementations were found:
<CallContext<'a, T> as neon::context::Context<'a>>
error[E0277]: the trait bound `&'a mut CallContext<'_, neon::prelude::JsObject>: neon::context::Context<'_>` is not satisfied
--> native/lib.rs:121:9
|
121 | obj.set(&mut cx, "buf", buf)?;
| ^^^ the trait `neon::context::Context<'_>` is not implemented for `&'a mut CallContext<'_, neon::prelude::JsObject>`
|
= help: the following implementations were found:
<CallContext<'a, T> as neon::context::Context<'a>>
I started with plaintext_from_u64
just taking the context as mut cx: FunctionContext
, which is how encode_num
accepts it, but that then causes problems as soon as I want to call plaintext_from_u64
more than once, because "value borrowed after move", and if I try to borrow in the calls, I get "expected struct CallContext
, found mutable reference. I've dug around in the neon examples repo, looking for exported functions that pass a context into an internal function, but I haven't been able to find anything so far, which is... frustrating.
What is the compiler-approved approach to this problem?