Skip to content

Commit 4a2c3fd

Browse files
committed
Update tokio-fetch
1 parent 7b90168 commit 4a2c3fd

4 files changed

Lines changed: 15 additions & 65 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ members = [
1111
[workspace.dependencies.neon]
1212
git = "https://github.com/neon-bindings/neon.git"
1313
branch = "class-attribute"
14+
features = ["tokio"]
1415

1516
[profile.release]
1617
lto = true

examples/tokio-fetch/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,5 @@ crate-type = ["cdylib"]
1111

1212
[dependencies]
1313
neon.workspace = true
14-
once_cell = "1"
1514
reqwest = { version = "0.12.24", features = ["json"] }
16-
tokio = { version = "1", features = ["rt-multi-thread"] }
1715
serde = { version = "1", features = ["derive"] }

examples/tokio-fetch/src/lib.rs

Lines changed: 13 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
1-
use neon::prelude::*;
2-
use once_cell::sync::OnceCell;
1+
use neon::{prelude::*, types::extract::Error};
32
use serde::Deserialize;
4-
use tokio::runtime::Runtime;
53

64
#[derive(Deserialize)]
75
struct NodeRelease {
86
version: String,
97
date: String,
108
}
119

12-
// Return a global tokio runtime or create one if it doesn't exist.
13-
// Throws a JavaScript exception if the `Runtime` fails to create.
14-
fn runtime<'a, C: Context<'a>>(cx: &mut C) -> NeonResult<&'static Runtime> {
15-
static RUNTIME: OnceCell<Runtime> = OnceCell::new();
16-
17-
RUNTIME.get_or_try_init(|| Runtime::new().or_else(|err| cx.throw_error(err.to_string())))
18-
}
19-
2010
// Get the version of the currently running node process from [`process.version`](https://nodejs.org/api/process.html#processversion)
21-
fn node_version<'a, C: Context<'a>>(cx: &mut C) -> NeonResult<String> {
11+
fn node_version(cx: &mut Cx) -> NeonResult<String> {
2212
let version = cx
2313
.global::<JsObject>("process")?
2414
.get::<JsString, _, _>(cx, "version")?
@@ -46,55 +36,17 @@ async fn fetch_node_release(version: &str) -> Result<Option<NodeRelease>, reqwes
4636
Ok(version)
4737
}
4838

49-
// Get the release date of the currently running Node process.
50-
// Returns a `Promise<string>` and executes asynchronously on the `tokio`
51-
// thread pool.
52-
fn node_release_date(mut cx: FunctionContext) -> JsResult<JsPromise> {
53-
let rt = runtime(&mut cx)?;
54-
let version = node_version(&mut cx)?;
55-
let channel = cx.channel();
56-
57-
// Create a JavaScript promise and a `deferred` handle for resolving it.
58-
// It is important to be careful not to perform failable actions after
59-
// creating the promise to avoid an unhandled rejection.
60-
let (deferred, promise) = cx.promise();
61-
62-
// Spawn an `async` task on the tokio runtime. Only Rust types that are
63-
// `Send` may be moved into this block. `Context` may not be passed and all
64-
// JavaScript values must first be converted to Rust types.
65-
//
66-
// This task will _not_ block the JavaScript main thread.
67-
rt.spawn(async move {
68-
// Inside this block, it is possible to `await` Rust `Future`
69-
let release = fetch_node_release(&version).await;
70-
71-
// Settle the promise from the result of a closure. JavaScript exceptions
72-
// will be converted to a Promise rejection.
73-
//
74-
// This closure will execute on the JavaScript main thread. It should be
75-
// limited to converting Rust types to JavaScript values. Expensive operations
76-
// should be performed outside of it.
77-
deferred.settle_with(&channel, move |mut cx| {
78-
// Convert a `reqwest::Error` to a JavaScript exception
79-
let release = release.or_else(|err| cx.throw_error(err.to_string()))?;
80-
81-
match release {
82-
// Resolve the promise with the release date
83-
Some(release) => Ok(cx.string(release.date)),
84-
85-
// Reject the `Promise` if the version could not be found
86-
None => cx.throw_error(format!("Could not find version: {}", version)),
87-
}
88-
});
89-
});
90-
91-
// Return the promise back to JavaScript
92-
Ok(promise)
93-
}
39+
#[neon::export(async)]
40+
fn node_release_date(
41+
cx: &mut Cx,
42+
) -> NeonResult<impl Future<Output = Result<String, Error>> + use<>> {
43+
let version = node_version(cx)?;
9444

95-
#[neon::main]
96-
fn main(mut cx: ModuleContext) -> NeonResult<()> {
97-
cx.export_function("nodeReleaseDate", node_release_date)?;
45+
Ok(async move {
46+
let release = fetch_node_release(&version)
47+
.await?
48+
.ok_or_else(|| format!("Could not find version: {version}"))?;
9849

99-
Ok(())
50+
Ok(release.date)
51+
})
10052
}

0 commit comments

Comments
 (0)