Skip to content

Commit 167c7fb

Browse files
dhermankjvalencik
andcommitted
feat(neon): JsFunction::bind() and Object::prop() (#1056)
Implements `JsFunction::bind()`, which creates a builder for calling a function using the `Try{From,Into}Js` traits. ```rust let n = f.bind(&mut cx) .args((1, 2, 3))? .arg(4)? .arg_with(|cx| Ok(cx.number(5)))? .call::<f64>()?; ``` Also implements `Object::prop()`, which creates a builder for accessing object properties using the `Try{From,Into}Js` traits. ```rust let x: f64 = obj .prop(&mut cx, "x") .get()?; obj.prop(&mut cx, "y") .set(x)?; let s: String = obj.prop(&mut cx, "toString") .bind()? .call()?; ``` Finally, it offers a shorthand convenience method `Object::method()`, which extracts an object property and binds it as a method: ```rust let s: String = obj.method(&mut cx, "toString").call()?; ``` --------- Co-authored-by: K.J. Valencik <[email protected]>
1 parent f3568f1 commit 167c7fb

File tree

21 files changed

+891
-278
lines changed

21 files changed

+891
-278
lines changed

crates/neon/src/context/mod.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@
4545
//! # use neon::prelude::*;
4646
//! fn log(cx: &mut Cx, msg: &str) -> NeonResult<()> {
4747
//! cx.global::<JsObject>("console")?
48-
//! .call_method_with(cx, "log")?
49-
//! .arg(cx.string(msg))
50-
//! .exec(cx)?;
51-
//!
48+
//! .method(cx, "log")?
49+
//! .arg(msg)?
50+
//! .exec()?;
5251
//! Ok(())
5352
//! }
5453
//!
@@ -107,22 +106,18 @@
107106
//! # fn iterate(mut cx: FunctionContext) -> JsResult<JsUndefined> {
108107
//! let iterator = cx.argument::<JsObject>(0)?; // iterator object
109108
//! let next: Handle<JsFunction> = // iterator's `next` method
110-
//! iterator.get(&mut cx, "next")?;
109+
//! iterator.prop(&mut cx, "next").get()?;
111110
//! let mut numbers = vec![]; // results vector
112111
//! let mut done = false; // loop controller
113112
//!
114113
//! while !done {
115114
//! done = cx.execute_scoped(|mut cx| { // temporary scope
116115
//! let obj: Handle<JsObject> = next // temporary object
117-
//! .call_with(&cx)
118-
//! .this(iterator)
119-
//! .apply(&mut cx)?;
120-
//! let number: Handle<JsNumber> = // temporary number
121-
//! obj.get(&mut cx, "value")?;
122-
//! numbers.push(number.value(&mut cx));
123-
//! let done: Handle<JsBoolean> = // temporary boolean
124-
//! obj.get(&mut cx, "done")?;
125-
//! Ok(done.value(&mut cx))
116+
//! .bind(&mut cx)
117+
//! .this(iterator)?
118+
//! .call()?;
119+
//! numbers.push(obj.prop(&mut cx, "value").get()?); // temporary number
120+
//! obj.prop(&mut cx, "done").get() // temporary boolean
126121
//! })?;
127122
//! }
128123
//! # Ok(cx.undefined())
@@ -505,7 +500,7 @@ pub trait Context<'a>: ContextInternal<'a> {
505500
/// # let v: Handle<JsFunction> =
506501
/// {
507502
/// let global = cx.global_object();
508-
/// global.get(cx, name)
503+
/// global.prop(cx, name).get()
509504
/// }
510505
/// # ?;
511506
/// # Ok(v)

crates/neon/src/event/channel.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,11 @@ type Callback = Box<dyn FnOnce(sys::Env) + Send + 'static>;
7575
/// // loop. This _will_ block the event loop while executing.
7676
/// channel.send(move |mut cx| {
7777
/// let callback = callback.into_inner(&mut cx);
78-
/// let this = cx.undefined();
79-
/// let args = vec![
80-
/// cx.null().upcast::<JsValue>(),
81-
/// cx.number(result).upcast(),
82-
/// ];
8378
///
84-
/// callback.call(&mut cx, this, args)?;
79+
/// callback
80+
/// .bind(&mut cx)
81+
/// .args(((), result))?
82+
/// .exec()?;
8583
///
8684
/// Ok(())
8785
/// });

crates/neon/src/event/mod.rs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,31 +78,28 @@
7878
//! // loop. This _will_ block the event loop while executing.
7979
//! channel.send(move |mut cx| {
8080
//! let callback = callback.into_inner(&mut cx);
81-
//! let this = cx.undefined();
82-
//! let args = match result {
81+
//!
82+
//! match result {
8383
//! Ok(psd) => {
8484
//! // Extract data from the parsed file.
85-
//! let width = cx.number(psd.width());
86-
//! let height = cx.number(psd.height());
87-
//!
88-
//! // Save the data in a result object.
89-
//! let obj = cx.empty_object();
90-
//! obj.set(&mut cx, "width", width)?;
91-
//! obj.set(&mut cx, "height", height)?;
92-
//! vec![
93-
//! cx.null().upcast::<JsValue>(),
94-
//! obj.upcast(),
95-
//! ]
85+
//! let obj = cx.empty_object()
86+
//! .prop(&mut cx, "width").set(psd.width())?
87+
//! .prop("height").set(psd.height())?
88+
//! .this();
89+
//!
90+
//! callback
91+
//! .bind(&mut cx)
92+
//! .args(((), obj))?
93+
//! .exec()?;
9694
//! }
9795
//! Err(err) => {
98-
//! let err = cx.string(err.to_string());
99-
//! vec![
100-
//! err.upcast::<JsValue>(),
101-
//! ]
96+
//! use neon::types::extract::Error;
97+
//! callback
98+
//! .bind(&mut cx)
99+
//! .arg(Error::from(err))?
100+
//! .exec()?;
102101
//! }
103-
//! };
104-
//!
105-
//! callback.call(&mut cx, this, args)?;
102+
//! }
106103
//!
107104
//! Ok(())
108105
//! });

crates/neon/src/handle/mod.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,18 @@
2727
//!
2828
//! ## Example
2929
//!
30-
//! This Neon function takes an object as its argument, extracts two properties,
31-
//! `width` and `height`, and multiplies them together as numbers. Each JavaScript
32-
//! value in the calculation is stored locally in a `Handle`.
30+
//! This Neon function takes an object as its argument, extracts an object property,
31+
//! `homeAddress`, and then extracts a string property, `zipCode` from that second
32+
//! object. Each JavaScript value in the calculation is stored locally in a `Handle`.
3333
//!
3434
//! ```
3535
//! # use neon::prelude::*;
36-
//! fn area(mut cx: FunctionContext) -> JsResult<JsNumber> {
37-
//! let rect: Handle<JsObject> = cx.argument(0)?;
38-
//!
39-
//! let width: Handle<JsNumber> = rect.get(&mut cx, "width")?;
40-
//! let w: f64 = width.value(&mut cx);
41-
//!
42-
//! let height: Handle<JsNumber> = rect.get(&mut cx, "height")?;
43-
//! let h: f64 = height.value(&mut cx);
44-
//!
45-
//! Ok(cx.number(w * h))
36+
//! # use neon::export;
37+
//! #[export]
38+
//! fn customer_zip_code<'cx>(cx: &mut FunctionContext<'cx>, customer: Handle<'cx, JsObject>) -> JsResult<'cx, JsString> {
39+
//! let home_address: Handle<JsObject> = customer.prop(cx, "homeAddress").get()?;
40+
//! let zip_code: Handle<JsString> = home_address.prop(cx, "zipCode").get()?;
41+
//! Ok(zip_code)
4642
//! }
4743
//! ```
4844

0 commit comments

Comments
 (0)