diff --git "a/src/rust-learn/napi-rs/1.\345\257\274\345\207\272class.md" "b/src/rust-learn/napi-rs/1.\345\257\274\345\207\272class.md" new file mode 100644 index 0000000000..685e228e30 --- /dev/null +++ "b/src/rust-learn/napi-rs/1.\345\257\274\345\207\272class.md" @@ -0,0 +1,66 @@ +# 导出Class + +```rust +use std::path::{Path, PathBuf}; +use napi_derive::napi; +use tokio::{fs}; +use futures::prelude::*; +use napi::bindgen_prelude::*; + +// 此处可以通过js_name制定类名 +#[napi(js_name = "ClassDemoName")] +pub struct ClassDemo { + name: String +} + +#[napi] +impl ClassDemo { + // 设置当前的new方法为构造函数 + #[napi(constructor)] + pub fn new() -> Self { + ClassDemo { + name: String::from("123") + } + } + + // 设置一个工厂方法,必须返回当前的类, 最后会变成一个静态的方法,并且返回当前类的实例 + #[napi(factory)] + pub fn with_initial_count(count: u32) -> ClassDemo { + ClassDemo { + name: String::from(count.to_string()) + } + } + + // 设置一个普通的异步方法 + #[napi] + pub async fn read_dir(&self, query: String) -> napi::Result { + let res = fs::read_to_string(PathBuf::from(query)).await?; + Ok(res) + } + + // 设置一个普通方法 + #[napi] + pub fn return_string(&self) -> napi::Result { + Ok(String::from("value")) + } + + // 设置一个getter + #[napi(getter)] + pub fn name(&self) -> &str { + self.name.as_str() + } + + // 设置一个setter + #[napi(setter)] + pub fn set_name(&mut self, s: String) { + self.name = s; + } + + // 设置方法的可访问性 writable / enumerable / configurable + #[napi(writable = false)] + pub fn get_name(&self) -> &str { + self.name.as_str() + } +} +``` + diff --git "a/src/rust-learn/napi-rs/2.\345\257\274\345\207\272\345\274\202\346\255\245\345\207\275\346\225\260.md" "b/src/rust-learn/napi-rs/2.\345\257\274\345\207\272\345\274\202\346\255\245\345\207\275\346\225\260.md" new file mode 100644 index 0000000000..45c7b78255 --- /dev/null +++ "b/src/rust-learn/napi-rs/2.\345\257\274\345\207\272\345\274\202\346\255\245\345\207\275\346\225\260.md" @@ -0,0 +1,25 @@ +# 导出异步函数 + +```rust +[dependencies] +napi = { version = "2", features = ["async"] } +``` + +```rust +use futures::prelude::*; +use napi::bindgen_prelude::*; +use tokio::fs; + +#[napi] +async fn read_file_async(path: String) -> Result { + fs::read(path) + .map(|r| match r { + Ok(content) => Ok(content.into()), + Err(e) => Err(Error::new( + Status::GenericFailure, + format!("failed to read file, {}", e), + )), + }) + .await +} +``` \ No newline at end of file diff --git "a/src/rust-learn/napi-rs/3.\345\234\250rust\344\270\255\346\211\247\350\241\214js\347\232\204Promise.md" "b/src/rust-learn/napi-rs/3.\345\234\250rust\344\270\255\346\211\247\350\241\214js\347\232\204Promise.md" new file mode 100644 index 0000000000..8e34642b33 --- /dev/null +++ "b/src/rust-learn/napi-rs/3.\345\234\250rust\344\270\255\346\211\247\350\241\214js\347\232\204Promise.md" @@ -0,0 +1,23 @@ +# 在rust中执行js的Promise +```rust +use napi::bindgen_prelude::*; + +#[napi] +pub async fn async_plus_100(p: Promise) -> Result { + let v = p.await?; + Ok(v + 100) +} +``` + +```js +import { asyncPlus100 } from './index.js' + +const fx = 20 +const result = await asyncPlus100( + new Promise((resolve) => { + setTimeout(() => resolve(fx), 50) + }), +) + +console.log(result) // 120 +``` \ No newline at end of file diff --git "a/src/rust-learn/napi-rs/4.\346\263\250\345\205\245this\347\224\250\346\235\245\350\216\267\345\217\226js\350\277\220\350\241\214\346\227\266\350\256\276\347\275\256\347\232\204\345\261\236\346\200\247.md" "b/src/rust-learn/napi-rs/4.\346\263\250\345\205\245this\347\224\250\346\235\245\350\216\267\345\217\226js\350\277\220\350\241\214\346\227\266\350\256\276\347\275\256\347\232\204\345\261\236\346\200\247.md" new file mode 100644 index 0000000000..dc8dfc336a --- /dev/null +++ "b/src/rust-learn/napi-rs/4.\346\263\250\345\205\245this\347\224\250\346\235\245\350\216\267\345\217\226js\350\277\220\350\241\214\346\227\266\350\256\276\347\275\256\347\232\204\345\261\236\346\200\247.md" @@ -0,0 +1,61 @@ +# 注入this用来获取js运行时设置的属性 + +## 在类中使用 + +```js +import { QueryEngine } from './index.js' + +const qe = new QueryEngine() +qe.refCount = 3 +console.log(qe.getRefCount()) // 3 +``` + +在上面的例子中, QueryEngine 并没有声明和初始化 refCount, 但是js动态设置了,rust要怎么做才能获取到这个属性呢? + +```rust +#[napi] +use napi::bindgen_prelude::*; +use napi_derive::napi; + +pub struct QueryEngine {} + +#[napi] +impl QueryEngine { + #[napi(constructor)] + pub fn new() -> Result { + Ok(Self {}) + } + + #[napi] + pub fn get_ref_count(&self, this: This) -> Result> { + this.get::("refCount") + } +} +``` + + + + +## 在函数中使用 +```rust +import { Width, plusOne } from './index.js' + +const width = new Width(1) +console.log(plusOne(width)) // 2 +``` +在上面的例子中,plusOne可能有自己的this上下文 + +```rust +use napi::bindgen_prelude::*; +use napi_derive::napi; + +#[napi(constructor)] +pub struct Width { + pub value: i32, +} + +#[napi] +pub fn plus_one(this: This<&Width>) -> i32 { + this.value + 1 +} +``` \ No newline at end of file diff --git a/src/rust-learn/napi-rs/index.md b/src/rust-learn/napi-rs/index.md new file mode 100644 index 0000000000..9996df4fc5 --- /dev/null +++ b/src/rust-learn/napi-rs/index.md @@ -0,0 +1 @@ +# napi-rs \ No newline at end of file