Repository: metacall/core (language: rust)

Issue:
rs-port: clarify how to capture variables from the surrounding env in `MetacallFutureHandler`
## Description
According to using `fn(...)` instead of `impl Fn(...) -> ()` due to lifetime issues, We cannot use closures to capture the variables from the surrounding env because that's impossible in function points. 
https://github.com/metacall/core/blob/9632ba27cd1819f2e100c84c531485dfc7c95a7e/source/ports/rs_port/src/types/metacall_future.rs#L16

The documentation doesn't offer details about passing data to the future and using it in the handlers.


**Example for trying to capture a variable from the surrounding env:**
```rust
use metacall::{MetacallValue, MetacallFuture, metacall};
 
fn run() {
  let x = 10;
  fn resolve(result: impl MetacallValue, data: impl MetacallValue) {
      println!("X = {x}");
  }
   
  fn reject(result: impl MetacallValue, data: impl MetacallValue) {
      println!("X = {x}");
  }
    
  let future = metacall::<MetacallFuture>("async_function", [1]).unwrap();
  future.then(resolve).catch(reject).await_fut();
}
```

**Error:**
```
error[E0434]: can't capture dynamic environment in a fn item
 --> src/run.rs:7:23
  |
7 |       println!("X = {x}");
  |                         ^ cannot capture dynamic environment in a fn item
  |
  = help: use the `|| { ... }` closure form instead
```

## Solution
There's a method used to solve this problem, [`MetacallFuture.data(data: impl MetacallValue)`](https://github.com/metacall/core/blob/9632ba27cd1819f2e100c84c531485dfc7c95a7e/source/ports/rs_port/src/types/metacall_future.rs#L158C27-L158C52), but the documentation doesn't clarify what its benefit is and when we should use it. Users may be confused about what this method is, and how they can pass data from the surrounding environment to use it instead of using closures. So, I suggest improving this method's documentation with some examples.



Discussion / hints:

Fix patch:
diff --git a/source/ports/rs_port/src/types/metacall_future.rs b/source/ports/rs_port/src/types/metacall_future.rs
index 2f804acd7..46a8c436c 100644
--- a/source/ports/rs_port/src/types/metacall_future.rs
+++ b/source/ports/rs_port/src/types/metacall_future.rs
@@ -16,20 +16,40 @@ use std::{
 pub type MetacallFutureHandler = fn(Box<dyn MetacallValue>, Box<dyn MetacallValue>);
 
 /// Represents MetacallFuture. Keep in mind that it's not supported to pass a future as an argument.
-/// Usage example: ...
+/// 
+/// ## **Usage example:**
+/// 
+/// **Javascript Code:**
+/// ```javascript
+/// function doubleValueAfterTime(value, delay) {
+///     return new Promise((resolve, reject) => {
+///         setTimeout(() => {
+///             if (typeof value === 'number') {
+///                 resolve(value * 2); // Resolves if the value is a number
+///             } else {
+///                 reject('Error: The provided value is not a number.'); // Rejects if the value is not a number
+///             }
+///         }, delay);
+///     });
+/// }
 /// ```
+/// 
+/// **Calling Example:**
+/// ```rust
 /// use metacall::{MetacallValue, MetacallFuture, metacall};
-///
-/// fn resolve(result: impl MetacallValue, data: impl MetacallValue) {
-///     println!("Resolve:: result: {:#?}, data: {:#?}", result, data);
-/// }
-///
-/// fn reject(result: impl MetacallValue, data: impl MetacallValue) {
-///     println!("Reject:: result: {:#?}, data: {:#?}", result, data);
+/// fn runner(x: i32) {
+/// 
+///     fn resolve(result: impl MetacallValue, data: impl MetacallValue) {
+///         println!("Resolve:: result: {:#?}, data: {:#?}", result, data); // 
+///     }
+/// 
+///     fn reject(error: impl MetacallValue, data: impl MetacallValue) {
+///         println!("Reject:: error: {:#?}, data: {:#?}", error, data);
+///     }
+/// 
+///     let future = metacall::<MetacallFuture>("doubleValueAfterTime", [1, 2000]).unwrap();
+///     future.then(resolve).catch(reject).await_fut();
 /// }
-///
-/// let future = metacall::<MetacallFuture>("async_function", [1]).unwrap();
-/// future.then(resolve).catch(reject).await_fut();
 /// ```
 #[repr(C)]
 pub struct MetacallFuture {
@@ -141,20 +161,88 @@ impl MetacallFuture {
     }
 
     /// Adds a resolve callback.
+    /// 
+    /// ## **Usage example:**
+    /// 
+    /// 
+    /// ```javascript
+    /// // Javascript script
+    /// 
+    /// function func_always_rejects(value, delay) {
+    ///     return new Promise((resolve) => {
+    ///         resolve('Resolve message.'); 
+    ///     });
+    /// }
+    /// ```
+    /// **Calling Example:**
+    /// 
+    /// ```rust
+    /// use metacall::{MetacallValue, MetacallFuture, metacall_no_args};
+    /// fn calling() {
+    ///     fn reject(result: impl MetacallValue, _: impl MetacallValue) {
+    ///         println!("Resolve:: {:#?}", result); // Resolve:: "Resolve message"
+    ///     }
+    /// 
+    ///     let future = metacall_no_args::<MetacallFuture>("func_always_resolve").unwrap();
+    ///     future.then(resolve).catch(reject).await_fut();
+    /// }
+    /// ```
     pub fn then(mut self, resolve: MetacallFutureHandler) -> Self {
         self.resolve = Some(resolve);
-
+        
         self
     }
-
+    
     /// Adds a reject callback.
+    /// 
+    /// ## **Usage example:**
+    /// 
+    /// ```javascript
+    /// // Javascript script
+    /// function func_always_rejects(value, delay) {
+    ///     return new Promise((_, reject) => {
+    ///         reject('Error: Reject message.'); 
+    ///     });
+    /// }
+    /// ```
+    /// **Calling Example:**
+    /// ```rust
+    /// use metacall::{MetacallValue, MetacallFuture, metacall_no_args};
+    /// fn calling() {
+    ///     fn reject(error: impl MetacallValue, _: impl MetacallValue) {
+    ///         println!("Reject:: error: {:#?}", error); // Reject:: error: "Error: Reject message"
+    ///     }
+    /// 
+    ///     let future = metacall_no_args::<MetacallFuture>("func_always_rejects").unwrap();
+    ///     future.then(resolve).catch(reject).await_fut();
+    /// }
+    /// ```
     pub fn catch(mut self, reject: MetacallFutureHandler) -> Self {
         self.reject = Some(reject);
 
         self
     }
 
-    /// Adds data.
+    /// Adds data to use it inside the `resolver` and `reject`.
+    /// 
+    /// Example:
+    /// ```rust
+    /// use metacall::{MetacallValue, MetacallFuture, metacall};
+    /// 
+    /// fn run() {
+    ///   let x = 10;
+    ///   fn resolve(result: impl MetacallValue, data: impl MetacallValue) {
+    ///       println!("X = {data}");
+    ///   }
+    ///    
+    ///   fn reject(result: impl MetacallValue, data: impl MetacallValue) {
+    ///       println!("X = {data}");
+    ///   }
+    ///     
+    ///   let future = metacall::<MetacallFuture>("async_function", [1]).unwrap();
+    ///   future.then(resolve).catch(reject),data(x).await_fut();
+    /// }
+    /// ```
     pub fn data(mut self, data: impl MetacallValue) -> Self {
         unsafe { drop(Box::from_raw(self.data)) };
 


Test patch: