neon-bindings / neon

Rust bindings for writing safe and fast native Node.js modules.
https://www.neon-bindings.com/
Apache License 2.0
8.05k stars 284 forks source link

Tutorial from the docs is failing to compile #929

Closed postpersonality closed 2 years ago

postpersonality commented 2 years ago
Hi there! I've been trying to accomplish tutorial from Getting Started docs. It fails for me for the to_object function. I get error 13 obj.set(&mut cx, "title", title)?; --- -^^^^^^
the trait neon::context::Context<'_> is not implemented for &mut impl Context<'a>

Any ideas how to fix that? I can participate fixing docs if they are just outdated.

kjvalencik commented 2 years ago

This looks like you might be grabbing a &mut reference to something that is already a &mut reference.

In other words, your code is passing a &mut &mut Context. Try removing the &mut.

obj.set(cx, "title", title)?;

I think this probably isn't a docs issue since it would be correct with an owned context. It's dependent on the code around it.

postpersonality commented 2 years ago

Surrounding code made exactly as the tutorial recommends:

use neon::prelude::*;

struct Book {
    pub title: String,
    pub author: String,
    pub year: u32,
}

impl Book {
    fn to_object<'a>(&self, cx: &mut impl Context<'a>) -> JsResult<'a, JsObject> {
        let obj = cx.empty_object();
        let title = cx.string(self.title);
        obj.set(&mut cx, "title", title)?;
        let author = cx.string(self.author);
        obj.set(&mut cx, "author", author)?;
        let year = cx.number(self.year);
        obj.set(&mut cx, "year", year)?;
        Ok(obj)
    }
}

#[neon::main]
pub fn main(mut cx: ModuleContext) -> NeonResult<()> {
    let book = Book {
        title: "Chadwick the Crab".to_string(),
        author: "Priscilla Cummings".to_string(),
        year: 2009,
    };
    let obj = book.to_object(&mut cx)?;
    cx.export_value("chadwick", obj)?;
    Ok(())
}
kjvalencik commented 2 years ago

I can't seem to find these docs. Can you provide a link?

postpersonality commented 2 years ago

Posted above the complete code I have. Here are the docs https://neon-bindings.com/docs/objects

kjvalencik commented 2 years ago

Thanks for reporting! I'll leave this issue open to fix those docs. FYI, it seems like the only problem is the &mut should be removed on these lines.

postpersonality commented 2 years ago

Removing &mut brings another issue:

error[E0507]: cannot move out of `self.title` which is behind a shared reference
  --> src/lib.rs:26:31
   |
26 |         let title = cx.string(self.title);
   |                               ^^^^^^^^^^ move occurs because `self.title` has type `String`, which does not implement the `Copy` trait
postpersonality commented 2 years ago

Correct code for the piece is

impl Book {
    fn to_object<'a>(&self, cx: &mut impl Context<'a>) -> JsResult<'a, JsObject> {
        let obj = cx.empty_object();

        let title = cx.string(&self.title);
        obj.set(cx, "title", title)?;

        let author = cx.string(&self.author);
        obj.set(cx, "author", author)?;

        let year = cx.number(self.year);
        obj.set(cx, "year", year)?;

        Ok(obj)
    }
}