From 3ed738c896e1a87428a8157a7c1449e3a4afcb3f Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 1 Nov 2024 14:45:32 +0200 Subject: [PATCH 01/12] feat: introduce `rs_port2` Clone [rs-port2](https://github.com/hulxv/metacall-rs) to metacall source --- source/ports/rs_port2/.gitignore | 1 + source/ports/rs_port2/Cargo.lock | 14 + source/ports/rs_port2/Cargo.toml | 10 + source/ports/rs_port2/README.md | 4 + .../crates/metacall-bindings/.gitignore | 1 + .../crates/metacall-bindings/Cargo.toml | 8 + .../metacall-bindings/src/call/async.rs | 274 +++++++++ .../crates/metacall-bindings/src/call/mod.rs | 2 + .../crates/metacall-bindings/src/call/sync.rs | 211 +++++++ .../crates/metacall-bindings/src/class.rs | 107 ++++ .../crates/metacall-bindings/src/func.rs | 60 ++ .../crates/metacall-bindings/src/handle.rs | 77 +++ .../crates/metacall-bindings/src/lib.rs | 231 ++++++++ .../crates/metacall-bindings/src/loader.rs | 84 +++ .../crates/metacall-bindings/src/object.rs | 77 +++ .../crates/metacall-bindings/src/register.rs | 86 +++ .../metacall-bindings/src/value/cast.rs | 212 +++++++ .../metacall-bindings/src/value/create.rs | 212 +++++++ .../crates/metacall-bindings/src/value/mod.rs | 531 ++++++++++++++++++ .../crates/metacall-bindings/src/version.rs | 82 +++ source/ports/rs_port2/src/lib.rs | 3 + 21 files changed, 2287 insertions(+) create mode 100644 source/ports/rs_port2/.gitignore create mode 100644 source/ports/rs_port2/Cargo.lock create mode 100644 source/ports/rs_port2/Cargo.toml create mode 100644 source/ports/rs_port2/README.md create mode 100644 source/ports/rs_port2/crates/metacall-bindings/.gitignore create mode 100644 source/ports/rs_port2/crates/metacall-bindings/Cargo.toml create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/call/async.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/call/mod.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/call/sync.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/class.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/func.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/handle.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/lib.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/loader.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/object.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/register.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/value/cast.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/value/create.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs create mode 100644 source/ports/rs_port2/crates/metacall-bindings/src/version.rs create mode 100644 source/ports/rs_port2/src/lib.rs diff --git a/source/ports/rs_port2/.gitignore b/source/ports/rs_port2/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/source/ports/rs_port2/.gitignore @@ -0,0 +1 @@ +/target diff --git a/source/ports/rs_port2/Cargo.lock b/source/ports/rs_port2/Cargo.lock new file mode 100644 index 000000000..1ed22dbaf --- /dev/null +++ b/source/ports/rs_port2/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "metacall-bindings" +version = "0.1.0" + +[[package]] +name = "metacall-rs" +version = "0.1.0" +dependencies = [ + "metacall-bindings", +] diff --git a/source/ports/rs_port2/Cargo.toml b/source/ports/rs_port2/Cargo.toml new file mode 100644 index 000000000..7a45d476d --- /dev/null +++ b/source/ports/rs_port2/Cargo.toml @@ -0,0 +1,10 @@ +workspace = { members = ["crates/metacall-bindings"] } +[package] +name = "metacall-rs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +metacall-bindings = { path = "crates/metacall-bindings" } diff --git a/source/ports/rs_port2/README.md b/source/ports/rs_port2/README.md new file mode 100644 index 000000000..e8d23f834 --- /dev/null +++ b/source/ports/rs_port2/README.md @@ -0,0 +1,4 @@ +> Under development. Don't use it in production! + +# Metacall Rust Port +Improved version for [Metacall Rust Port](https://github.com/metacall/core/tree/develop/source/ports/rs_port). diff --git a/source/ports/rs_port2/crates/metacall-bindings/.gitignore b/source/ports/rs_port2/crates/metacall-bindings/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/.gitignore @@ -0,0 +1 @@ +/target diff --git a/source/ports/rs_port2/crates/metacall-bindings/Cargo.toml b/source/ports/rs_port2/crates/metacall-bindings/Cargo.toml new file mode 100644 index 000000000..b5f5c7156 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "metacall-bindings" +version = "0.1.0" +edition = "2021" +build = "build.rs" +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/call/async.rs b/source/ports/rs_port2/crates/metacall-bindings/src/call/async.rs new file mode 100644 index 000000000..02dd291f6 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/call/async.rs @@ -0,0 +1,274 @@ +extern "C" { + /// Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (this call blocks). + /// + /// # Parameters + /// + /// - `name`: The name of the function to be called asynchronously. + /// - `args`: Array of pointers to the values to be passed to the function. + /// - `resolve_callback`: Pointer to a function that will be executed when the task is completed. + /// - `arg1`: Value representing the result of the future resolution. + /// - `arg2`: A reference to `data` that will be used as a closure for the chain. + /// - Returns: Value containing the result of the operation, wrapped into a future. + /// - `reject_callback`: Pointer to a function that will be executed in case of a task error (identical signature to `resolve_callback`). + /// - `data`: Pointer to a context that will act as a closure for the chain. + /// + /// # Returns + /// + /// Pointer to the result value returned by either `resolve_callback` or `reject_callback`, wrapped in a future. + pub fn metacall_await( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + resolve_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Awaits a promise and registers a callback to be executed when a future is resolved. + /// + /// # Parameters + /// + /// - `f`: Pointer to the future. + /// - `resolve_callback`: Function pointer executed upon task completion. + /// - `arg1`: Result of the future resolution. + /// - `arg2`: Reference to the `data` used as closure. + /// - `reject_callback`: Function pointer executed in case of task error (same signature as `resolve_callback`). + /// - `data`: Pointer to a context acting as closure for the chain. + /// + /// # Returns + /// + /// Pointer to the result value returned by `resolve_callback` or `reject_callback`, wrapped in a future. + pub fn metacall_await_future( + f: *mut ::std::os::raw::c_void, + resolve_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Executes an asynchronous call with an argument size and registers a callback for the future resolution (blocking). + /// + /// # Parameters + /// + /// - `name`: The function name. + /// - `args`: Array of argument pointers. + /// - `size`: Number of elements in the `args` array. + /// - `resolve_callback`: Function called on task completion (same as above). + /// - `reject_callback`: Function called on task error (same as above). + /// - `data`: Pointer to a context acting as a closure. + /// + /// # Returns + /// + /// Result value wrapped in a future returned by the callbacks. + pub fn metacall_await_s( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + resolve_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls an asynchronous function by passing a function pointer and argument array, awaiting the result. + /// + /// # Parameters + /// + /// - `func`: Pointer to the function. + /// - `args`: Array of argument pointers. + /// - `resolve_callback`: Function pointer executed when the task completes. + /// - `reject_callback`: Function pointer executed when the task errors (identical to `resolve_callback`). + /// - `data`: Closure context pointer. + /// + /// # Returns + /// + /// Pointer to the future result. + pub fn metacallfv_await( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + resolve_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls an asynchronous function with argument size and awaits the result. + /// + /// # Parameters + /// + /// - `func`: Function pointer. + /// - `args`: Argument pointer array. + /// - `size`: Number of elements in `args`. + /// - `resolve_callback`: Pointer executed on task completion. + /// - `reject_callback`: Pointer executed on task error. + /// - `data`: Pointer to closure context. + /// + /// # Returns + /// + /// Pointer to the future result. + pub fn metacallfv_await_s( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + resolve_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Executes an asynchronous function call using a map of keys and values, and awaits the result. + /// + /// # Parameters + /// + /// - `func`: Function pointer. + /// - `keys`: Pointer array representing argument keys. + /// - `values`: Pointer array representing argument values. + /// - `size`: Size of the `keys` and `values` arrays. + /// - `resolve_callback`: Called on task success. + /// - `reject_callback`: Called on task error. + /// - `data`: Context used as closure for the callbacks. + /// + /// # Returns + /// + /// Future-wrapped result. + pub fn metacallfmv_await_s( + func: *mut ::std::os::raw::c_void, + keys: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + size: usize, + resolve_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls an asynchronous function anonymously using the given function pointer and serialized argument buffer. + /// + /// # Parameters + /// + /// - `func`: Pointer to the function to be called. + /// - `buffer`: String representing an array of serialized arguments. + /// - `size`: Size of the `buffer`. + /// - `allocator`: Pointer to the allocator used for allocating the result. + /// - `resolve_callback`: Function pointer executed when the task completes successfully. + /// - `arg1`: Pointer to the result of the future resolution. + /// - `arg2`: Reference to `data`, which acts as a closure for the callback chain. + /// - Returns: Pointer to the result, wrapped in a future to be returned by the function. + /// - `reject_callback`: Function pointer executed when the task fails (same signature as `resolve_callback`). + /// - `data`: Pointer to a context that acts as a closure for the callback chain. + /// + /// # Returns + /// + /// Pointer to the result returned by `resolve_callback` or `reject_callback`, wrapped in a future. + pub fn metacallfs_await( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls an asynchronous function anonymously using the given function pointer and serialized map buffer. + /// + /// # Parameters + /// + /// - `func`: Pointer to the function to be called. + /// - `buffer`: String representing a map of serialized arguments. + /// - `size`: Size of the `buffer`. + /// - `allocator`: Pointer to the allocator used for allocating the result. + /// - `resolve_callback`: Function pointer executed when the task completes successfully. + /// - `arg1`: Pointer to the result of the future resolution. + /// - `arg2`: Reference to `data`, which acts as a closure for the callback chain. + /// - Returns: Pointer to the result, wrapped in a future to be returned by the function. + /// - `reject_callback`: Function pointer executed when the task fails (same signature as `resolve_callback`). + /// - `data`: Pointer to a context that acts as a closure for the callback chain. + /// + /// # Returns + /// + /// Pointer to the result returned by `resolve_callback` or `reject_callback`, wrapped in a future. + pub fn metacallfms_await( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/call/mod.rs b/source/ports/rs_port2/crates/metacall-bindings/src/call/mod.rs new file mode 100644 index 000000000..70008d90e --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/call/mod.rs @@ -0,0 +1,2 @@ +pub mod sync; +pub mod r#async; \ No newline at end of file diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/call/sync.rs b/source/ports/rs_port2/crates/metacall-bindings/src/call/sync.rs new file mode 100644 index 000000000..598ca27ce --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/call/sync.rs @@ -0,0 +1,211 @@ +use crate::value::MetacallValueID; + +extern "C" { + /// Calls a function anonymously by value array `args`. + /// + /// # Parameters + /// - `name`: Name of the function. + /// - `args`: Array of pointers to data. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallv( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by value array `args` with a specified size. + /// + /// # Parameters + /// - `name`: Name of the function. + /// - `args`: Array of pointers to data. + /// - `size`: Number of elements of the call. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallv_s( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by handle `handle` and value array `args`. + /// + /// # Parameters + /// - `handle`: Handle where the function belongs. + /// - `name`: Name of the function. + /// - `args`: Array of pointers to data. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallhv( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by handle `handle`, value array `args`, and a specified size. + /// + /// # Parameters + /// - `handle`: Handle where the function belongs. + /// - `name`: Name of the function. + /// - `args`: Array of pointers to data. + /// - `size`: Number of elements of the call. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallhv_s( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by variable arguments `va_args`. + /// + /// # Parameters + /// - `name`: Name of the function. + /// - `va_args`: Variadic function parameters. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacall(name: *const ::std::os::raw::c_char, ...) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by type array `ids` and variable arguments `va_args`. + /// + /// # Parameters + /// - `name`: Name of the function. + /// - `ids`: Array of types referring to `va_args`. + /// - `va_args`: Variadic function parameters. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallt( + name: *const ::std::os::raw::c_char, + ids: *const MetacallValueID, + ... + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by type array `ids` with variable arguments `va_args` and size. + /// + /// # Parameters + /// - `name`: Name of the function. + /// - `ids`: Array of types referring to `va_args`. + /// - `size`: Number of elements of the call. + /// - `va_args`: Variadic function parameters. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallt_s( + name: *const ::std::os::raw::c_char, + ids: *const MetacallValueID, + size: usize, + ... + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by handle `handle`, type array `ids`, variable arguments `va_args`, and size. + /// + /// # Parameters + /// - `handle`: Pointer to the handle returned by `metacall_load_from_*`. + /// - `name`: Name of the function. + /// - `ids`: Array of types referring to `va_args`. + /// - `size`: Number of elements of the call. + /// - `va_args`: Variadic function parameters. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallht_s( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ids: *const MetacallValueID, + size: usize, + ... + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by value array `args` and function `func`. + /// + /// # Parameters + /// - `func`: Reference to the function to be called. + /// - `args`: Array of pointers to data. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallfv( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by value array `args`, function `func`, and specified size. + /// + /// # Parameters + /// - `func`: Reference to the function to be called. + /// - `args`: Array of pointers to data. + /// - `size`: Number of function arguments. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallfv_s( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by variable arguments `va_args` and function `func`. + /// + /// # Parameters + /// - `func`: Reference to the function to be called. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallf(func: *mut ::std::os::raw::c_void, ...) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by function `func` and serial `buffer` of size `size`. + /// + /// # Parameters + /// - `func`: Reference to the function to be called. + /// - `buffer`: String representing an array to be deserialized into function arguments. + /// - `size`: Size of the string `buffer`. + /// - `allocator`: Pointer to the allocator that will allocate the value. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallfs( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by value map (`keys -> values`) and function `func`. + /// + /// # Parameters + /// - `func`: Reference to the function to be called. + /// - `keys`: Array of values representing argument keys. + /// - `values`: Array of values representing argument values data. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallfmv( + func: *mut ::std::os::raw::c_void, + keys: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a function anonymously by function `func` and serial `buffer` of size `size`. + /// + /// # Parameters + /// - `func`: Reference to the function to be called. + /// - `buffer`: String representing a map to be deserialized into function arguments. + /// - `size`: Size of the string `buffer`. + /// - `allocator`: Pointer to the allocator that will allocate the value. + /// + /// # Returns + /// Pointer to a value containing the result of the call. + pub fn metacallfms( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/class.rs b/source/ports/rs_port2/crates/metacall-bindings/src/class.rs new file mode 100644 index 000000000..89545ae40 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/class.rs @@ -0,0 +1,107 @@ +use crate::value::MetacallValueID; + +extern "C" { + /// Retrieves a class by its name. + /// + /// # Parameters + /// + /// - `name`: The name of the class. + /// + /// # Returns + /// + /// Pointer to the class reference, or `null` if the class does not exist. + pub fn metacall_class(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; + + /// Calls a class method anonymously using an array of arguments. + /// + /// This function assumes no method overloading and performs type conversion on the values. + /// + /// # Parameters + /// + /// - `cls`: Pointer to the class. + /// - `name`: Name of the method to call. + /// - `args`: Array of pointers to the method's arguments. + /// - `size`: Number of elements in the `args` array. + /// + /// # Returns + /// + /// Pointer to the result of the method call. + pub fn metacallv_class( + cls: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Calls a class method anonymously with an expected return type, aiding in method overloading resolution. + /// + /// # Parameters + /// + /// - `cls`: Pointer to the class. + /// - `name`: Name of the method to call. + /// - `ret`: Expected return value type. + /// - `args`: Array of pointers to the method's arguments. + /// - `size`: Number of elements in the `args` array. + /// + /// # Returns + /// + /// Pointer to the result of the method call. + pub fn metacallt_class( + cls: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ret: MetacallValueID, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a new object instance from a class using the given constructor arguments. + /// + /// # Parameters + /// + /// - `cls`: Pointer to the class. + /// - `name`: Name of the new object. + /// - `args`: Array of pointers to the constructor parameters. + /// - `size`: Number of elements in the `args` array. + /// + /// # Returns + /// + /// Pointer to the newly created object instance. + pub fn metacall_class_new( + cls: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Retrieves a class attribute by its key name. + /// + /// # Parameters + /// + /// - `cls`: Pointer to the class. + /// - `key`: Name of the attribute to retrieve. + /// + /// # Returns + /// + /// Pointer to the class attribute value, or `NULL` if an error occurred. + pub fn metacall_class_static_get( + cls: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; + + /// Sets a class attribute by its key name. + /// + /// # Parameters + /// + /// - `cls`: Pointer to the class. + /// - `key`: Name of the attribute to set. + /// - `value`: Value to set. + /// + /// # Returns + /// + /// A non-zero integer if an error occurred. + pub fn metacall_class_static_set( + cls: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + v: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/func.rs b/source/ports/rs_port2/crates/metacall-bindings/src/func.rs new file mode 100644 index 000000000..72c1126fd --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/func.rs @@ -0,0 +1,60 @@ +use crate::value::MetacallValueID; + +extern "C" { + + /// Retrieves a function by `name`. + /// + /// # Parameters + /// - `name`: Name of the function. + /// + /// # Returns + /// Function reference, null if the function does not exist. + pub fn metacall_function(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; + + /// Retrieves the function parameter type ID. + /// + /// # Parameters + /// - `func`: Pointer to the function obtained from `metacall_function`. + /// - `parameter`: Index of the parameter to be retrieved. + /// - `id`: Parameter type ID that will be returned. + /// + /// # Returns + /// Zero if the parameter index exists and function is valid, non-zero otherwise. + pub fn metacall_function_parameter_type( + func: *mut ::std::os::raw::c_void, + parameter: usize, + id: *mut MetacallValueID, + ) -> ::std::os::raw::c_int; + + /// Retrieves the function return type ID. + /// + /// # Parameters + /// - `func`: Pointer to the function obtained from `metacall_function`. + /// - `id`: Return type ID of the function. + /// + /// # Returns + /// Zero if the function is valid, non-zero otherwise. + pub fn metacall_function_return_type( + func: *mut ::std::os::raw::c_void, + id: *mut MetacallValueID, + ) -> ::std::os::raw::c_int; + + /// Retrieves the minimum number of arguments accepted by the function. + /// + /// # Parameters + /// - `func`: Function reference. + /// + /// # Returns + /// Number of arguments. + pub fn metacall_function_size(func: *mut ::std::os::raw::c_void) -> usize; + + /// Checks if the function is asynchronous or synchronous. + /// + /// # Parameters + /// - `func`: Function reference. + /// + /// # Returns + /// - `true` if the function is asynchronous. + /// - `false` if the function is synchronous. + pub fn metacall_function_async(func: *mut ::std::os::raw::c_void) -> bool; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/handle.rs b/source/ports/rs_port2/crates/metacall-bindings/src/handle.rs new file mode 100644 index 000000000..09bfb0181 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/handle.rs @@ -0,0 +1,77 @@ +extern "C" { + /// Initializes an empty handler into a loader by `name`. + /// + /// # Parameters + /// - `loader`: Pointer to the loader to which the handle belongs. + /// - `name`: Name of the handle. + /// - `handle_ptr`: On success, returns the pointer to the created handle, otherwise `NULL`. + /// + /// # Returns + /// Zero on success, non-zero on error. + pub fn metacall_handle_initialize( + loader: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + handle_ptr: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; + + /// Populates the objects of `handle_src` into `handle_dest`. + /// + /// # Parameters + /// - `handle_dest`: Handle where the objects from `handle_src` will be stored. + /// - `handle_src`: Handle from where the objects will be copied. + /// + /// # Returns + /// Zero on success, non-zero on error. + pub fn metacall_handle_populate( + handle_dest: *mut ::std::os::raw::c_void, + handle_src: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; + + /// Retrieves a function by `name` from a specific `handle`. + /// + /// # Parameters + /// - `handle`: Pointer to the handle returned by `metacall_load_from_*`. + /// - `name`: Name of the function. + /// + /// # Returns + /// Function reference, null if the function does not exist. + pub fn metacall_handle_function( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; + + /// Retrieves the handle by `name`. + /// + /// # Parameters + /// - `tag`: Extension of the script. + /// - `name`: Name of the handle. + /// + /// # Returns + /// Handle reference, or null if the function does not exist. + pub fn metacall_handle( + tag: *const ::std::os::raw::c_char, + name: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; + + /// Retrieves the name of a `handle`. + /// + /// # Parameters + /// - `handle`: Pointer to the handle to be retrieved. + /// + /// # Returns + /// String that references the handle. + pub fn metacall_handle_id(handle: *mut ::std::os::raw::c_void) + -> *const ::std::os::raw::c_char; + + /// Returns a value representing the handle as a map of functions (or values). + /// + /// # Parameters + /// - `handle`: Reference to the handle to be described. + /// + /// # Returns + /// A value of type map on success, or null otherwise. + pub fn metacall_handle_export( + handle: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/lib.rs b/source/ports/rs_port2/crates/metacall-bindings/src/lib.rs new file mode 100644 index 000000000..746e98196 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/lib.rs @@ -0,0 +1,231 @@ +pub mod call; +pub mod class; +pub mod func; +pub mod handle; +pub mod loader; +pub mod value; +pub mod object; +pub mod register; +pub mod version; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct MetacallInitializeConfigurationType { + pub tag: *mut ::std::os::raw::c_char, + pub options: *mut ::std::os::raw::c_void, +} + +extern "C" { + /// Returns the default serializer used by MetaCall. + /// + /// # Returns + /// A pointer to a string containing the name of the serializer to be used with serialization methods. + pub fn metacall_serial() -> *const ::std::os::raw::c_char; + + /// Disables MetaCall logs. Must be called before `metacall_initialize`. + /// + /// When initializing MetaCall, a default log is set to stdout if none is defined. + /// To benchmark or disable this default log, call this function before `metacall_initialize`. + pub fn metacall_log_null(); + + /// Sets flags in the MetaCall library. + /// + /// # Parameters + /// - `flags`: A combination of flags referring to definitions `METACALL_FLAGS_*`. + pub fn metacall_flags(flags: ::std::os::raw::c_int); + + /// Initializes the MetaCall library. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_initialize() -> ::std::os::raw::c_int; + + /// Initializes the MetaCall library with configuration arguments. + /// + /// # Parameters + /// - `initialize_config`: Pointer to a configuration structure to be loaded in memory with data to be injected. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_initialize_ex( + initialize_config: *mut MetacallInitializeConfigurationType, + ) -> ::std::os::raw::c_int; + + /// Initializes MetaCall application arguments. + /// + /// # Parameters + /// - `argc`: Number of additional parameters to be passed to the runtime. + /// - `argv`: Additional parameters to be passed to the runtime when initializing. + pub fn metacall_initialize_args( + argc: ::std::os::raw::c_int, + argv: *mut *mut ::std::os::raw::c_char, + ); + + /// Gets the number of arguments in which MetaCall was initialized. + /// + /// # Returns + /// An integer equal to or greater than zero. + pub fn metacall_argc() -> ::std::os::raw::c_int; + + /// Gets the arguments in which MetaCall was initialized. + /// + /// # Returns + /// A pointer to an array of strings with the additional arguments. + pub fn metacall_argv() -> *mut *mut ::std::os::raw::c_char; + + /// Checks if a script context is loaded by the specified tag. + /// + /// # Parameters + /// - `tag`: The extension of the script (if NULL, returns the status of the whole MetaCall instance). + /// + /// # Returns + /// - `0` if context is initialized; different from `0` otherwise. + pub fn metacall_is_initialized(tag: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; + + /// Gets the number of function call arguments supported by MetaCall. + /// + /// # Returns + /// The number of supported arguments. + pub fn metacall_args_size() -> usize; + + /// Sets an execution path for the extension script specified by the tag. + /// + /// # Parameters + /// - `tag`: The extension of the script. + /// - `path`: The path to be loaded. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_execution_path( + tag: *const ::std::os::raw::c_char, + path: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; + + /// Sets an execution path for the extension script specified by the tag with length. + /// + /// # Parameters + /// - `tag`: The extension of the script. + /// - `tag_length`: Length of the extension of the tag. + /// - `path`: The path to be loaded. + /// - `path_length`: Length of the path. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_execution_path_s( + tag: *const ::std::os::raw::c_char, + tag_length: usize, + path: *const ::std::os::raw::c_char, + path_length: usize, + ) -> ::std::os::raw::c_int; + + /// Clears a handle from memory and unloads related resources. + /// + /// # Parameters + /// + /// - `handle`: Pointer to the handle to be unloaded. + /// + /// # Returns + /// + /// Returns zero if successful, and a non-zero value otherwise. + pub fn metacall_clear(handle: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; + + /// Retrieves the plugin extension handle used for loading plugins. + /// + /// # Returns + /// + /// Pointer to the extension handle, or `null` if it failed to load. + pub fn metacall_plugin_extension() -> *mut ::std::os::raw::c_void; + + /// Retrieves the handle containing all the functionality of the plugins from the core. + /// + /// # Returns + /// + /// Pointer to the core plugin handle, or `null` if it failed to load. + pub fn metacall_plugin_core() -> *mut ::std::os::raw::c_void; + + /// Retrieves the plugin extension path used for accessing the plugins folder. + /// + /// # Returns + /// + /// Pointer to a string containing the core plugin path, or `null` if it failed to load the plugin extension. + pub fn metacall_plugin_path() -> *const ::std::os::raw::c_char; + + /// Destroys the MetaCall library. + /// + /// # Returns + /// + /// Returns zero if successful, and a non-zero value otherwise. + pub fn metacall_destroy() -> ::std::os::raw::c_int; + + /// Converts the specified value into a serialized string. + /// + /// # Parameters + /// + /// - `name`: Name of the serialization format to be used. + /// - `v`: Reference to the value to serialize. + /// - `size`: Output parameter that will contain the size of the newly allocated string. + /// - `allocator`: Pointer to the allocator that will allocate the string. + /// + /// # Returns + /// + /// Pointer to a newly allocated string containing the stringified value. + pub fn metacall_serialize( + name: *const ::std::os::raw::c_char, + v: *mut ::std::os::raw::c_void, + size: *mut usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_char; + + /// Converts the specified string buffer into a value. + /// + /// # Parameters + /// + /// - `name`: Name of the serialization format to be used. + /// - `buffer`: String to be deserialized. + /// - `size`: Size of the string buffer. + /// - `allocator`: Pointer to the allocator that will allocate the value. + /// + /// # Returns + /// + /// Pointer to a newly allocated value representing the string. This value must be freed when no longer needed. + pub fn metacall_deserialize( + name: *const ::std::os::raw::c_char, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Retrieves the value contained within a throwable object. + /// + /// # Parameters + /// + /// - `th`: Pointer to the throwable object. + /// + /// # Returns + /// + /// Pointer to the value inside the throwable, or `NULL` in case of an error. + pub fn metacall_throwable_value(th: *mut ::std::os::raw::c_void) + -> *mut ::std::os::raw::c_void; + + /// Provides information about all loaded objects. + /// + /// # Parameters + /// + /// - `size`: Size in bytes of the return buffer (output parameter). + /// - `allocator`: Pointer to the allocator that will allocate the string. + /// + /// # Returns + /// + /// A string containing introspection information about the loaded objects. + pub fn metacall_inspect( + size: *mut usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_char; + + /// Provides information about all loaded objects as a value. + /// + /// # Returns + /// + /// Pointer to a value containing introspection information. + pub fn metacall_inspect_value() -> *mut ::std::os::raw::c_void; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/loader.rs b/source/ports/rs_port2/crates/metacall-bindings/src/loader.rs new file mode 100644 index 000000000..1b92194c3 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/loader.rs @@ -0,0 +1,84 @@ +extern "C" { + + /// Obtains the loader instance by `tag`. + /// + /// # Parameters + /// - `tag`: Tag in which the loader is identified, typically the extension of the script. + /// + /// # Returns + /// Pointer to the loader by `tag`. + pub fn metacall_loader(tag: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; + + /// Loads a script from a file specified by the path. + /// + /// # Parameters + /// - `tag`: The extension of the script. + /// - `paths`: Array of file paths. + /// - `size`: Size of the array of paths. + /// - `handle`: Optional pointer to a reference of the loaded handle. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_load_from_file( + tag: *const ::std::os::raw::c_char, + paths: *mut *const ::std::os::raw::c_char, + size: usize, + handle: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; + + /// Loads a script from memory. + /// + /// # Parameters + /// - `tag`: The extension of the script. + /// - `buffer`: Memory block representing the script string. + /// - `size`: Size of the memory block. + /// - `handle`: Optional pointer to a reference of the loaded handle. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_load_from_memory( + tag: *const ::std::os::raw::c_char, + buffer: *const ::std::os::raw::c_char, + size: usize, + handle: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; + + /// Loads a package of scripts from a file specified by the path into the loader defined by the extension. + /// + /// # Parameters + /// - `tag`: The extension of the script. + /// - `path`: Path of the package. + /// - `handle`: Optional pointer to a reference of the loaded handle. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_load_from_package( + tag: *const ::std::os::raw::c_char, + path: *const ::std::os::raw::c_char, + handle: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; + + /// Loads a list of scripts from a configuration specified by the path into the loader. + /// + /// The configuration format is: + /// ```json + /// { + /// "language_id": "", + /// "path": "", + /// "scripts": ["", "", ..., ""] + /// } + /// ``` + /// + /// # Parameters + /// - `path`: Path of the configuration. + /// - `handle`: Optional pointer to a reference of the loaded handle. + /// - `allocator`: Pointer to the allocator that will allocate the configuration. + /// + /// # Returns + /// - `0` if success; different from `0` otherwise. + pub fn metacall_load_from_configuration( + path: *const ::std::os::raw::c_char, + handle: *mut *mut ::std::os::raw::c_void, + allocator: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} \ No newline at end of file diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/object.rs b/source/ports/rs_port2/crates/metacall-bindings/src/object.rs new file mode 100644 index 000000000..e6cf83f62 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/object.rs @@ -0,0 +1,77 @@ +use crate::value::MetacallValueID; + +extern "C" { + /// Calls an object method anonymously using an array of arguments. + /// + /// This function assumes no method overloading and performs type conversion on the values. + /// + /// # Parameters + /// + /// - `obj`: Pointer to the object. + /// - `name`: Name of the method to call. + /// - `args`: Array of pointers to the method's arguments. + /// - `size`: Number of elements in the `args` array. + /// + /// # Returns + /// + /// Pointer to the result of the method call. + pub fn metacallv_object( + obj: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Calls an object method anonymously with an expected return type, aiding in method overloading resolution. + /// + /// # Parameters + /// + /// - `obj`: Pointer to the object. + /// - `name`: Name of the method to call. + /// - `ret`: Expected return value type. + /// - `args`: Array of pointers to the method's arguments. + /// - `size`: Number of elements in the `args` array. + /// + /// # Returns + /// + /// Pointer to the result of the method call. + pub fn metacallt_object( + obj: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ret: MetacallValueID, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Retrieves an attribute from an object by its key name. + /// + /// # Parameters + /// + /// - `obj`: Pointer to the object. + /// - `key`: Name of the attribute to retrieve. + /// + /// # Returns + /// + /// Pointer to the object attribute value, or `NULL` if an error occurred. + pub fn metacall_object_get( + obj: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; + + /// Sets an attribute on an object by its key name. + /// + /// # Parameters + /// + /// - `obj`: Pointer to the object. + /// - `key`: Name of the attribute to set. + /// - `value`: Value to set. + /// + /// # Returns + /// + /// A non-zero integer if an error occurred. + pub fn metacall_object_set( + obj: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + v: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/register.rs b/source/ports/rs_port2/crates/metacall-bindings/src/register.rs new file mode 100644 index 000000000..630432a79 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/register.rs @@ -0,0 +1,86 @@ +use crate::value::MetacallValueID; + +extern "C" { + /// Registers a function by name `name` and arguments `va_args`. + /// + /// # Parameters + /// - `name`: Name of the function (if it is `NULL`, the function is not registered into the host scope). + /// - `invoke`: Pointer to the function invoke interface (argc, argv, data). + /// - `func`: Will set the pointer to the function if the parameter is not null. + /// - `return_type`: Type of return value. + /// - `size`: Number of function arguments. + /// - `va_args`: Variadic function parameter types. + /// + /// # Returns + /// Pointer to the value containing the result of the call. + pub fn metacall_register( + name: *const ::std::os::raw::c_char, + invoke: ::std::option::Option< + unsafe extern "C" fn( + arg1: usize, + arg2: *mut *mut ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + func: *mut *mut ::std::os::raw::c_void, + return_type: MetacallValueID, + size: usize, + ... + ) -> ::std::os::raw::c_int; + + /// Registers a function by name `name` and arguments `types`. + /// + /// # Parameters + /// - `name`: Name of the function (if it is `NULL`, the function is not registered into the host scope). + /// - `invoke`: Pointer to the function invoke interface (argc, argv, data). + /// - `func`: Will set the pointer to the function if the parameter is not null. + /// - `return_type`: Type of return value. + /// - `size`: Number of function arguments. + /// - `types`: List of parameter types. + /// + /// # Returns + /// Pointer to the value containing the result of the call. + pub fn metacall_registerv( + name: *const ::std::os::raw::c_char, + invoke: ::std::option::Option< + unsafe extern "C" fn( + arg1: usize, + arg2: *mut *mut ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + func: *mut *mut ::std::os::raw::c_void, + return_type: MetacallValueID, + size: usize, + types: *mut MetacallValueID, + ) -> ::std::os::raw::c_int; + + /// Registers a function by name `name` and arguments `types` within a specified loader. + /// + /// # Parameters + /// - `loader`: Opaque pointer to the loader in which you want to register the function. + /// - `handle`: Opaque pointer to the handle in which you want to register the function (if `NULL`, it will be defined in the global scope of the loader). + /// - `name`: Name of the function (if `NULL`, the function is not registered into the host scope). + /// - `invoke`: Pointer to the function invoke interface (argc, argv, data). + /// - `return_type`: Type of return value. + /// - `size`: Number of function arguments. + /// - `types`: List of parameter types. + /// + /// # Returns + /// Zero if the function was registered properly, or a non-zero value otherwise. + pub fn metacall_register_loaderv( + loader: *mut ::std::os::raw::c_void, + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + invoke: ::std::option::Option< + unsafe extern "C" fn( + arg1: usize, + arg2: *mut *mut ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + return_type: MetacallValueID, + size: usize, + types: *mut MetacallValueID, + ) -> ::std::os::raw::c_int; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/value/cast.rs b/source/ports/rs_port2/crates/metacall-bindings/src/value/cast.rs new file mode 100644 index 000000000..5e56f9291 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/value/cast.rs @@ -0,0 +1,212 @@ +extern "C" { + /// Casts a value to a new type specified by `id`. + /// + /// # Parameters + /// - `v`: A pointer to the value to be cast. + /// - `id`: The new type ID of the value to be cast. + /// + /// # Returns + /// A pointer to the casted value, or a reference to `v` if the casting is between equivalent types. + pub fn metacall_value_cast( + v: *mut ::std::os::raw::c_void, + id: super::MetacallValueID, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a boolean. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to a boolean. + pub fn metacall_value_cast_bool(v: *mut *mut ::std::os::raw::c_void) + -> ::std::os::raw::c_uchar; + + /// Implicitly converts the value `v` to a character. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to a character. + pub fn metacall_value_cast_char(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_char; + + /// Implicitly converts the value `v` to a short integer. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to a short integer. + pub fn metacall_value_cast_short( + v: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_short; + + /// Implicitly converts the value `v` to an integer. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to an integer. + pub fn metacall_value_cast_int(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; + + /// Implicitly converts the value `v` to a long integer. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to a long integer. + pub fn metacall_value_cast_long(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_long; + + /// Implicitly converts the value `v` to a single precision floating point. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to a single precision floating point. + pub fn metacall_value_cast_float(v: *mut *mut ::std::os::raw::c_void) -> f32; + + /// Implicitly converts the value `v` to a double precision floating point. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// The value converted to a double precision floating point. + pub fn metacall_value_cast_double(v: *mut *mut ::std::os::raw::c_void) -> f64; + + /// Implicitly converts the value `v` to a C string (null-terminated). + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted C string. + pub fn metacall_value_cast_string( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_char; + + /// Implicitly converts the value `v` to a buffer. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted buffer. + pub fn metacall_value_cast_buffer( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to an array of values. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted array. + pub fn metacall_value_cast_array( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a map. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted map. + pub fn metacall_value_cast_map( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a pointer. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted value. + pub fn metacall_value_cast_ptr( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a future. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted future. + pub fn metacall_value_cast_future( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a function. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted function. + pub fn metacall_value_cast_function( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to null. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted null value. + pub fn metacall_value_cast_null( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a class. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted class. + pub fn metacall_value_cast_class( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to an object. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted object. + pub fn metacall_value_cast_object( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to an exception. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted exception. + pub fn metacall_value_cast_exception( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Implicitly converts the value `v` to a throwable. + /// + /// # Parameters + /// - `v`: A pointer to a pointer of the value to be converted. + /// + /// # Returns + /// A pointer to the converted throwable. + pub fn metacall_value_cast_throwable( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/value/create.rs b/source/ports/rs_port2/crates/metacall-bindings/src/value/create.rs new file mode 100644 index 000000000..d2a9e56e9 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/value/create.rs @@ -0,0 +1,212 @@ +extern "C" { + /// Creates a value from a boolean. + /// + /// # Parameters + /// - `b`: Boolean value that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_bool(b: ::std::os::raw::c_uchar) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a character. + /// + /// # Parameters + /// - `c`: Character value that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_char(c: ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a short integer. + /// + /// # Parameters + /// - `s`: Short integer that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_short(s: ::std::os::raw::c_short) -> *mut ::std::os::raw::c_void; + + /// Creates a value from an integer. + /// + /// # Parameters + /// - `i`: Integer value that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_int(i: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a long integer. + /// + /// # Parameters + /// - `l`: Long integer value that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_long(l: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a single-precision floating point number. + /// + /// # Parameters + /// - `f`: Float value that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_float(f: f32) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a double-precision floating point number. + /// + /// # Parameters + /// - `d`: Double value that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_double(d: f64) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a constant C string. + /// + /// # Parameters + /// - `str_`: Constant string (must be null-terminated) that will be copied into the value. + /// - `length`: Length of the constant string. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_string( + str_: *const ::std::os::raw::c_char, + length: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value buffer from a memory array. + /// + /// # Parameters + /// - `buffer`: Constant memory block that will be copied into the value. + /// - `size`: Size in bytes of the data contained in the array. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_buffer( + buffer: *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value array from an array of values. + /// + /// # Parameters + /// - `values`: Constant array of values that will be copied into the value list. + /// - `size`: Number of elements contained in the array. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_array( + values: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value map from an array of key-value tuples. + /// + /// # Parameters + /// - `tuples`: Constant array of tuples that will be copied into the value map. + /// - `size`: Number of elements contained in the map. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_map( + tuples: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a pointer. + /// + /// # Parameters + /// - `ptr`: Pointer to constant data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_ptr( + ptr: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a future object. + /// + /// # Parameters + /// - `f`: Pointer to constant data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_future( + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a function. + /// + /// # Parameters + /// - `f`: Pointer to the function data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_function( + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a function, binding a closure to it. + /// + /// # Parameters + /// - `f`: Pointer to the function data that will be copied into the value. + /// - `c`: Pointer to the closure to bind to the function. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_function_closure( + f: *mut ::std::os::raw::c_void, + c: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value of type null. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_null() -> *mut ::std::os::raw::c_void; + + /// Creates a value from a class object. + /// + /// # Parameters + /// - `c`: Pointer to the class data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_class( + c: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from an object. + /// + /// # Parameters + /// - `o`: Pointer to the object data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_object( + o: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from an exception. + /// + /// # Parameters + /// - `ex`: Pointer to the exception data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_exception( + ex: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Creates a value from a throwable object. + /// + /// # Parameters + /// - `th`: Pointer to the throwable data that will be copied into the value. + /// + /// # Returns + /// A pointer to the created value on success, or null otherwise. + pub fn metacall_value_create_throwable( + th: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs b/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs new file mode 100644 index 000000000..f141249f8 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs @@ -0,0 +1,531 @@ +pub mod cast; +pub mod create; +#[repr(C)] +pub enum MetacallValueID { + MetacallBool = 0, + MetacallChar = 1, + MetacallShort = 2, + MetacallInt = 3, + MetacallLong = 4, + MetacallFloat = 5, + MetacallDouble = 6, + MetacallString = 7, + MetacallBuffer = 8, + MetacallArray = 9, + MetacallMap = 10, + MetacallPtr = 11, + MetacallFuture = 12, + MetacallFunction = 13, + MetacallNull = 14, + MetacallClass = 15, + MetacallObject = 16, + MetacallException = 17, + MetacallThrowable = 18, + MetacallSize = 19, + MetacallInvalid = 20, +} + +extern "C" { + /// Returns the size of the value in bytes. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The size of the value in bytes. + pub fn metacall_value_size(v: *mut ::std::os::raw::c_void) -> usize; + + /// Returns the number of values that this value contains. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The number of values that the referenced value represents. + pub fn metacall_value_count(v: *mut ::std::os::raw::c_void) -> usize; + + /// Provides the type identifier (ID) of the value. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The type ID assigned to the value. + pub fn metacall_value_id(v: *mut ::std::os::raw::c_void) -> MetacallValueID; + + /// Provides the type identifier (ID) in a readable form (as a string). + /// + /// # Parameters + /// * `id`: The value type identifier. + /// + /// # Returns + /// A string related to the type ID. + pub fn metacall_value_id_name(id: MetacallValueID) -> *const ::std::os::raw::c_char; + + /// Provides the type identifier (ID) in a readable form (as a string) for the value. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// A string related to the type ID assigned to the value. + pub fn metacall_value_type_name( + v: *mut ::std::os::raw::c_void, + ) -> *const ::std::os::raw::c_char; + + /// Deep copies the given value, resetting its reference counter and ownership. + /// + /// # Parameters + /// * `v`: Reference to the value to be copied. + /// + /// # Returns + /// A copy of the value on success, or `null` otherwise. + pub fn metacall_value_copy(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Transfers ownership from the source value to the destination value, including the finalizer. + /// + /// # Parameters + /// * `src`: The source value that will lose ownership. + /// * `dst`: The destination value that will receive ownership. + pub fn metacall_value_move(src: *mut ::std::os::raw::c_void, dest: *mut ::std::os::raw::c_void); + + /// Converts the given value to a boolean. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a boolean. + pub fn metacall_value_to_bool(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_uchar; + + /// Converts the given value to a character. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a character. + pub fn metacall_value_to_char(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_char; + + /// Converts the given value to a short integer. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a short integer. + pub fn metacall_value_to_short(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_short; + + /// Converts the given value to an integer. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to an integer. + pub fn metacall_value_to_int(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; + + /// Converts the given value to a long integer. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a long integer. + pub fn metacall_value_to_long(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_long; + + /// Converts the given value to a single-precision floating point. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a float. + pub fn metacall_value_to_float(v: *mut ::std::os::raw::c_void) -> f32; + + /// Converts the given value to a double-precision floating point. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a double. + pub fn metacall_value_to_double(v: *mut ::std::os::raw::c_void) -> f64; + + /// Converts the given value to a C string (null-terminated). + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a C string. + pub fn metacall_value_to_string(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_char; + + /// Converts the given value to a memory block (buffer). + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a memory block. + pub fn metacall_value_to_buffer(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to an array of values. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to an array of values. + pub fn metacall_value_to_array( + v: *mut ::std::os::raw::c_void, + ) -> *mut *mut ::std::os::raw::c_void; + + /// Converts the given value to a map (array of tuples). + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a map (array of tuples, which are arrays of values). + pub fn metacall_value_to_map( + v: *mut ::std::os::raw::c_void, + ) -> *mut *mut ::std::os::raw::c_void; + + /// Converts the given value to a pointer. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a pointer. + pub fn metacall_value_to_ptr(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to a future. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a future. + pub fn metacall_value_to_future(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to a function. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a function. + pub fn metacall_value_to_function( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to null. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to null. + pub fn metacall_value_to_null(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to a class. + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to a class. + pub fn metacall_value_to_class(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to an object (instance of a class). + /// + /// # Parameters + /// * `v`: Reference to the value. + /// + /// # Returns + /// The value converted to an object. + pub fn metacall_value_to_object(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to an exception. + /// + /// # Parameters + /// - `v`: A pointer to the value to be converted. + /// + /// # Returns + /// A pointer to the value converted to an exception. + pub fn metacall_value_to_exception( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Converts the given value to a throwable. + /// + /// # Parameters + /// - `v`: A pointer to the value to be converted. + /// + /// # Returns + /// A pointer to the value converted to a throwable. + pub fn metacall_value_to_throwable( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a boolean value to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `b`: The boolean value to assign. + /// + /// # Returns + /// A pointer to the value with the assigned boolean. + pub fn metacall_value_from_bool( + v: *mut ::std::os::raw::c_void, + b: ::std::os::raw::c_uchar, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a character to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `c`: The character to assign. + /// + /// # Returns + /// A pointer to the value with the assigned character. + pub fn metacall_value_from_char( + v: *mut ::std::os::raw::c_void, + c: ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a short integer to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `s`: The short integer to assign. + /// + /// # Returns + /// A pointer to the value with the assigned short integer. + pub fn metacall_value_from_short( + v: *mut ::std::os::raw::c_void, + s: ::std::os::raw::c_short, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns an integer to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `i`: The integer to assign. + /// + /// # Returns + /// A pointer to the value with the assigned integer. + pub fn metacall_value_from_int( + v: *mut ::std::os::raw::c_void, + i: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a long integer to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `l`: The long integer to assign. + /// + /// # Returns + /// A pointer to the value with the assigned long integer. + pub fn metacall_value_from_long( + v: *mut ::std::os::raw::c_void, + l: ::std::os::raw::c_long, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a single-precision floating-point number to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `f`: The float to assign. + /// + /// # Returns + /// A pointer to the value with the assigned float. + pub fn metacall_value_from_float( + v: *mut ::std::os::raw::c_void, + f: f32, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a double-precision floating-point number to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `d`: The double to assign. + /// + /// # Returns + /// A pointer to the value with the assigned double. + pub fn metacall_value_from_double( + v: *mut ::std::os::raw::c_void, + d: f64, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a string to the specified value, truncating if necessary. + /// + /// This function does not add a null terminator if the string is truncated. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `str_`: A pointer to the null-terminated string to assign. + /// - `length`: The length of the string. + /// + /// # Returns + /// A pointer to the value with the assigned string. + pub fn metacall_value_from_string( + v: *mut ::std::os::raw::c_void, + str_: *const ::std::os::raw::c_char, + length: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns an array to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `buffer`: A pointer to the constant array to assign. + /// - `size`: The number of elements in the array. + /// + /// # Returns + /// A pointer to the value with the assigned array. + pub fn metacall_value_from_buffer( + v: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns an array of values to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `values`: A pointer to the constant array of values to assign. + /// - `size`: The number of values in the array. + /// + /// # Returns + /// A pointer to the value with the assigned array of values. + pub fn metacall_value_from_array( + v: *mut ::std::os::raw::c_void, + values: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns an array of tuples to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `tuples`: A pointer to the constant array of tuples to assign. + /// - `size`: The number of tuples in the array. + /// + /// # Returns + /// A pointer to the value with the assigned array of tuples. + pub fn metacall_value_from_map( + v: *mut ::std::os::raw::c_void, + tuples: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a pointer to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `ptr`: A pointer to be assigned to the value. + /// + /// # Returns + /// A pointer to the value with the assigned pointer. + pub fn metacall_value_from_ptr( + v: *mut ::std::os::raw::c_void, + ptr: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a future to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `f`: A pointer to the future to assign. + /// + /// # Returns + /// A pointer to the value with the assigned future. + pub fn metacall_value_from_future( + v: *mut ::std::os::raw::c_void, + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a function to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// - `f`: A pointer to the function to assign. + /// + /// # Returns + /// A pointer to the value with the assigned function. + pub fn metacall_value_from_function( + v: *mut ::std::os::raw::c_void, + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns a null value to the specified value. + /// + /// # Parameters + /// - `v`: A pointer to the value to be assigned. + /// + /// # Returns + /// A pointer to the value with the assigned null. + pub fn metacall_value_from_null(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; + + /// Assigns the specified class to the given value. + /// + /// # Parameters + /// - `v`: A pointer to the value to which the class will be assigned. + /// - `c`: A pointer to the class to be assigned to the value. + /// + /// # Returns + /// A pointer to the value with the assigned class. + pub fn metacall_value_from_class( + v: *mut ::std::os::raw::c_void, + c: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns the specified object to the given value. + /// + /// # Parameters + /// - `v`: A pointer to the value to which the object will be assigned. + /// - `o`: A pointer to the object to be assigned to the value. + /// + /// # Returns + /// A pointer to the value with the assigned object. + pub fn metacall_value_from_object( + v: *mut ::std::os::raw::c_void, + o: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns the specified exception to the given value. + /// + /// # Parameters + /// - `v`: A pointer to the value to which the exception will be assigned. + /// - `ex`: A pointer to the exception to be assigned to the value. + /// + /// # Returns + /// A pointer to the value with the assigned exception. + pub fn metacall_value_from_exception( + v: *mut ::std::os::raw::c_void, + ex: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Assigns the specified throwable to the given value. + /// + /// # Parameters + /// - `v`: A pointer to the value to which the throwable will be assigned. + /// - `th`: A pointer to the throwable to be assigned to the value. + /// + /// # Returns + /// A pointer to the value with the assigned throwable. + pub fn metacall_value_from_throwable( + v: *mut ::std::os::raw::c_void, + th: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; + + /// Destroys the specified value from the scope stack. + /// + /// # Parameters + /// - `v`: A pointer to the value to be destroyed. + pub fn metacall_value_destroy(v: *mut ::std::os::raw::c_void); +} diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/version.rs b/source/ports/rs_port2/crates/metacall-bindings/src/version.rs new file mode 100644 index 000000000..5a5e96fe9 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/src/version.rs @@ -0,0 +1,82 @@ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct MetacallVersionType { + pub major: ::std::os::raw::c_uint, + pub minor: ::std::os::raw::c_uint, + pub patch: ::std::os::raw::c_uint, + pub revision: *const ::std::os::raw::c_char, + pub str_: *const ::std::os::raw::c_char, + pub name: *const ::std::os::raw::c_char, +} + + +extern "C" { + /// Provides the module version structure. + /// + /// # Returns + /// + /// Pointer to a static struct containing the unpacked version information. + pub fn metacall_version() -> *const MetacallVersionType; + + /// Creates a packed hexadecimal representation of the module version. + /// + /// The format is `0xMMIIPPPP`, where: + /// - `M` is the major version. + /// - `I` is the minor version. + /// - `P` is the patch version. + /// + /// # Parameters + /// + /// - `major`: Unsigned integer representing the major version. + /// - `minor`: Unsigned integer representing the minor version. + /// - `patch`: Unsigned integer representing the patch version. + /// + /// # Returns + /// + /// Hexadecimal integer containing the packed version. + pub fn metacall_version_hex_make( + major: ::std::os::raw::c_uint, + minor: ::std::os::raw::c_uint, + patch: ::std::os::raw::c_uint, + ) -> u32; + + /// Provides the packed hexadecimal value of the module version. + /// + /// The format is `0xMMIIPPPP`, where: + /// - `M` is the major version. + /// - `I` is the minor version. + /// - `P` is the patch version. + /// + /// # Returns + /// + /// Hexadecimal integer containing the packed version. + pub fn metacall_version_hex() -> u32; + + /// Provides the module version as a string. + /// + /// # Returns + /// + /// Pointer to a static string containing the module version. + pub fn metacall_version_str() -> *const ::std::os::raw::c_char; + + /// Provides the module version revision as a string. + /// + /// # Returns + /// + /// Pointer to a static string containing the module version revision. + pub fn metacall_version_revision() -> *const ::std::os::raw::c_char; + + /// Provides the module version name as a string. + /// + /// # Returns + /// + /// Pointer to a static string containing the module version name. + pub fn metacall_version_name() -> *const ::std::os::raw::c_char; + + /// Provides information about the module. + /// + /// # Returns + /// + /// Pointer to a static string containing module information. + pub fn metacall_print_info() -> *const ::std::os::raw::c_char; +} diff --git a/source/ports/rs_port2/src/lib.rs b/source/ports/rs_port2/src/lib.rs new file mode 100644 index 000000000..37a8293f0 --- /dev/null +++ b/source/ports/rs_port2/src/lib.rs @@ -0,0 +1,3 @@ +pub fn hello_metacll() { + println!("Hello Metacall"); +} From 8b58d52739ad13df9726f093ab6b03fac02b3125 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 22 Nov 2024 16:01:45 +0200 Subject: [PATCH 02/12] working on metacall_value --- source/ports/rs_port2/src/lib.rs | 4 +- source/ports/rs_port2/src/value.rs | 68 ++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 source/ports/rs_port2/src/value.rs diff --git a/source/ports/rs_port2/src/lib.rs b/source/ports/rs_port2/src/lib.rs index 37a8293f0..825529b70 100644 --- a/source/ports/rs_port2/src/lib.rs +++ b/source/ports/rs_port2/src/lib.rs @@ -1,3 +1 @@ -pub fn hello_metacll() { - println!("Hello Metacall"); -} +mod value; \ No newline at end of file diff --git a/source/ports/rs_port2/src/value.rs b/source/ports/rs_port2/src/value.rs new file mode 100644 index 000000000..9c4883b48 --- /dev/null +++ b/source/ports/rs_port2/src/value.rs @@ -0,0 +1,68 @@ +use metacall_bindings::value::{ + create::metacall_value_create_long, metacall_value_destroy, metacall_value_from_long, + metacall_value_to_long, +}; +use std::ffi::c_long; + +trait Create { + fn new(value: T) -> Self; +} + +trait From { + fn from(&self, value: T) -> Self; +} + +trait To { + fn to(&self) -> T; +} + +struct Value(*mut std::os::raw::c_void); + +impl Create for Value { + fn new(value: i64) -> Self { + let val = unsafe { metacall_value_create_long(value as c_long) }; + Self(val) + } +} + +impl From for Value { + fn from(&self, value: i64) -> Self { + let val = unsafe { metacall_value_from_long(self.0, value as c_long) }; + Self(val) + } +} + +impl To for Value { + fn to(&self) -> i64 { + unsafe { metacall_value_to_long(self.0) as i64 } + } +} + +impl Drop for Value { + fn drop(&mut self) { + unsafe { + metacall_value_destroy(self.0); + } + } +} + +#[cfg(test)] +mod test { + // use metacall_bindings::{metacall_destroy, metacall_initialize}; + + use super::{Create, From, To, Value}; + + #[test] + fn metacall_create_value() { + // assert!(unsafe { metacall_initialize() } == 0); + let val = Value::new(123); + let result = val.to(); + assert!(result == 123); + val.from(33); + + let result = val.to(); + println!("{}", result); // 33 + assert!(result == 33); + // unsafe { metacall_destroy() }; + } +} From d0ebb147d16e1f48162a2c2dbcb8e741ac352896 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 22 Nov 2024 16:39:22 +0200 Subject: [PATCH 03/12] fix: missing `build.rs` --- .../crates/metacall-bindings/.gitignore | 1 + .../crates/metacall-bindings/build.rs | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 source/ports/rs_port2/crates/metacall-bindings/build.rs diff --git a/source/ports/rs_port2/crates/metacall-bindings/.gitignore b/source/ports/rs_port2/crates/metacall-bindings/.gitignore index ea8c4bf7f..a2e690e56 100644 --- a/source/ports/rs_port2/crates/metacall-bindings/.gitignore +++ b/source/ports/rs_port2/crates/metacall-bindings/.gitignore @@ -1 +1,2 @@ /target +!build.rs \ No newline at end of file diff --git a/source/ports/rs_port2/crates/metacall-bindings/build.rs b/source/ports/rs_port2/crates/metacall-bindings/build.rs new file mode 100644 index 000000000..0915869e7 --- /dev/null +++ b/source/ports/rs_port2/crates/metacall-bindings/build.rs @@ -0,0 +1,29 @@ +use std::env; + +fn main() { + // When running tests from CMake + if let Ok(val) = env::var("PROJECT_OUTPUT_DIR") { + // Link search path to build folder + println!("cargo:rustc-link-search=native={val}"); + + // Link against correct version of metacall + match env::var("CMAKE_BUILD_TYPE") { + Ok(val) => { + if val == "Debug" { + // Try to link the debug version when running tests + println!("cargo:rustc-link-lib=dylib=metacalld"); + } else { + println!("cargo:rustc-link-lib=dylib=metacall"); + } + } + Err(_) => { + println!("cargo:rustc-link-lib=dylib=metacall"); + } + } + } else { + // When building from Cargo + println!("cargo:rustc-link-lib=dylib=metacall") + } +} + + From 83e14048d189b45dd0e6916b8ca158261865ce23 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 22 Nov 2024 17:00:01 +0200 Subject: [PATCH 04/12] fix: dropping the `Value` in `Value::from` --- source/ports/rs_port2/src/value.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/ports/rs_port2/src/value.rs b/source/ports/rs_port2/src/value.rs index 9c4883b48..5eceaebd4 100644 --- a/source/ports/rs_port2/src/value.rs +++ b/source/ports/rs_port2/src/value.rs @@ -9,7 +9,7 @@ trait Create { } trait From { - fn from(&self, value: T) -> Self; + fn from(&mut self, value: T) -> &Self; } trait To { @@ -26,9 +26,9 @@ impl Create for Value { } impl From for Value { - fn from(&self, value: i64) -> Self { - let val = unsafe { metacall_value_from_long(self.0, value as c_long) }; - Self(val) + fn from(&mut self, value: i64) -> &Self { + self.0 = unsafe { metacall_value_from_long(self.0, value as c_long) }; + self } } @@ -55,7 +55,7 @@ mod test { #[test] fn metacall_create_value() { // assert!(unsafe { metacall_initialize() } == 0); - let val = Value::new(123); + let mut val = Value::new(123); let result = val.to(); assert!(result == 123); val.from(33); From bc4b98a7b0157f409e85f4b5a7865bd9ca04fcab Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 25 Nov 2024 22:12:23 +0200 Subject: [PATCH 05/12] refactor(bindings): remove `Metacall` prefix from `MetacallValueID` --- .../crates/metacall-bindings/src/value/mod.rs | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs b/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs index f141249f8..989652e9a 100644 --- a/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs +++ b/source/ports/rs_port2/crates/metacall-bindings/src/value/mod.rs @@ -1,28 +1,29 @@ pub mod cast; pub mod create; #[repr(C)] +#[derive(Debug, PartialEq, Eq)] pub enum MetacallValueID { - MetacallBool = 0, - MetacallChar = 1, - MetacallShort = 2, - MetacallInt = 3, - MetacallLong = 4, - MetacallFloat = 5, - MetacallDouble = 6, - MetacallString = 7, - MetacallBuffer = 8, - MetacallArray = 9, - MetacallMap = 10, - MetacallPtr = 11, - MetacallFuture = 12, - MetacallFunction = 13, - MetacallNull = 14, - MetacallClass = 15, - MetacallObject = 16, - MetacallException = 17, - MetacallThrowable = 18, - MetacallSize = 19, - MetacallInvalid = 20, + Bool = 0, + Char = 1, + Short = 2, + Int = 3, + Long = 4, + Float = 5, + Double = 6, + String = 7, + Buffer = 8, + Array = 9, + Map = 10, + Ptr = 11, + Future = 12, + Function = 13, + Null = 14, + Class = 15, + Object = 16, + Exception = 17, + Throwable = 18, + Size = 19, + Invalid = 20, } extern "C" { From 6d5660de024dcf35fff746091b8e928bd100273a Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 25 Nov 2024 22:15:07 +0200 Subject: [PATCH 06/12] feat(rs-port2): helper macro for checking of nullity of raw pointers --- source/ports/rs_port2/src/helpers.rs | 9 +++++++++ source/ports/rs_port2/src/lib.rs | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 source/ports/rs_port2/src/helpers.rs diff --git a/source/ports/rs_port2/src/helpers.rs b/source/ports/rs_port2/src/helpers.rs new file mode 100644 index 000000000..13920b86a --- /dev/null +++ b/source/ports/rs_port2/src/helpers.rs @@ -0,0 +1,9 @@ +/// A macro to check if a raw pointer is null and return a custom error. +#[macro_export] +macro_rules! check_null_ptr { + ($ptr:expr, $err:expr) => { + if $ptr.is_null() { + return Err($err.into()); + } + }; +} diff --git a/source/ports/rs_port2/src/lib.rs b/source/ports/rs_port2/src/lib.rs index 825529b70..127d2ca1c 100644 --- a/source/ports/rs_port2/src/lib.rs +++ b/source/ports/rs_port2/src/lib.rs @@ -1 +1,2 @@ -mod value; \ No newline at end of file +pub(crate) mod helpers; +pub mod value; From 5203822f93b879dff90a071f8feccc53aa86516e Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 25 Nov 2024 22:16:16 +0200 Subject: [PATCH 07/12] feat(rs-port2): add errors for `Value` --- source/ports/rs_port2/Cargo.lock | 63 ++++++++++++++++++++++++++++++ source/ports/rs_port2/Cargo.toml | 2 + source/ports/rs_port2/src/value.rs | 36 ++++++----------- 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/source/ports/rs_port2/Cargo.lock b/source/ports/rs_port2/Cargo.lock index 1ed22dbaf..9499ddd6f 100644 --- a/source/ports/rs_port2/Cargo.lock +++ b/source/ports/rs_port2/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + [[package]] name = "metacall-bindings" version = "0.1.0" @@ -10,5 +16,62 @@ version = "0.1.0" name = "metacall-rs" version = "0.1.0" dependencies = [ + "anyhow", "metacall-bindings", + "thiserror", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl", ] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/source/ports/rs_port2/Cargo.toml b/source/ports/rs_port2/Cargo.toml index 7a45d476d..c4fabf034 100644 --- a/source/ports/rs_port2/Cargo.toml +++ b/source/ports/rs_port2/Cargo.toml @@ -7,4 +7,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.93" metacall-bindings = { path = "crates/metacall-bindings" } +thiserror = "2.0.3" diff --git a/source/ports/rs_port2/src/value.rs b/source/ports/rs_port2/src/value.rs index 5eceaebd4..6141cc0bd 100644 --- a/source/ports/rs_port2/src/value.rs +++ b/source/ports/rs_port2/src/value.rs @@ -2,34 +2,20 @@ use metacall_bindings::value::{ create::metacall_value_create_long, metacall_value_destroy, metacall_value_from_long, metacall_value_to_long, }; -use std::ffi::c_long; - -trait Create { - fn new(value: T) -> Self; -} - -trait From { - fn from(&mut self, value: T) -> &Self; +use thiserror::Error; } -trait To { - fn to(&self) -> T; +#[derive(Error, Debug)] +pub enum ValueError { + #[error("Failed to create CString: {0}")] + CStringError(#[from] std::ffi::NulError), + #[error("Failed to convert CString to &str: {0}")] + Utf8Error(#[from] std::str::Utf8Error), + #[error("Null pointer encountered")] + NullPointer, + #[error("Unknown error")] + Unknown, } - -struct Value(*mut std::os::raw::c_void); - -impl Create for Value { - fn new(value: i64) -> Self { - let val = unsafe { metacall_value_create_long(value as c_long) }; - Self(val) - } -} - -impl From for Value { - fn from(&mut self, value: i64) -> &Self { - self.0 = unsafe { metacall_value_from_long(self.0, value as c_long) }; - self - } } impl To for Value { From 8cef261f1ed246b84e83940af6c3f9e3017a248b Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 25 Nov 2024 23:19:44 +0200 Subject: [PATCH 08/12] feat(rs-port2): build the base of the values - implement a constructor and `get_value` for - i16, i32, i64 - f32, f64 - String, &str - implement those methods for Value: - `is_null()` - `value_id()` - `value_id_name()` --- source/ports/rs_port2/src/value.rs | 54 --------- source/ports/rs_port2/src/value/float.rs | 51 ++++++++ source/ports/rs_port2/src/value/int.rs | 61 ++++++++++ source/ports/rs_port2/src/value/mod.rs | 135 ++++++++++++++++++++++ source/ports/rs_port2/src/value/string.rs | 44 +++++++ source/ports/rs_port2/src/value/tests.rs | 0 6 files changed, 291 insertions(+), 54 deletions(-) delete mode 100644 source/ports/rs_port2/src/value.rs create mode 100644 source/ports/rs_port2/src/value/float.rs create mode 100644 source/ports/rs_port2/src/value/int.rs create mode 100644 source/ports/rs_port2/src/value/mod.rs create mode 100644 source/ports/rs_port2/src/value/string.rs create mode 100644 source/ports/rs_port2/src/value/tests.rs diff --git a/source/ports/rs_port2/src/value.rs b/source/ports/rs_port2/src/value.rs deleted file mode 100644 index 6141cc0bd..000000000 --- a/source/ports/rs_port2/src/value.rs +++ /dev/null @@ -1,54 +0,0 @@ -use metacall_bindings::value::{ - create::metacall_value_create_long, metacall_value_destroy, metacall_value_from_long, - metacall_value_to_long, -}; -use thiserror::Error; -} - -#[derive(Error, Debug)] -pub enum ValueError { - #[error("Failed to create CString: {0}")] - CStringError(#[from] std::ffi::NulError), - #[error("Failed to convert CString to &str: {0}")] - Utf8Error(#[from] std::str::Utf8Error), - #[error("Null pointer encountered")] - NullPointer, - #[error("Unknown error")] - Unknown, -} -} - -impl To for Value { - fn to(&self) -> i64 { - unsafe { metacall_value_to_long(self.0) as i64 } - } -} - -impl Drop for Value { - fn drop(&mut self) { - unsafe { - metacall_value_destroy(self.0); - } - } -} - -#[cfg(test)] -mod test { - // use metacall_bindings::{metacall_destroy, metacall_initialize}; - - use super::{Create, From, To, Value}; - - #[test] - fn metacall_create_value() { - // assert!(unsafe { metacall_initialize() } == 0); - let mut val = Value::new(123); - let result = val.to(); - assert!(result == 123); - val.from(33); - - let result = val.to(); - println!("{}", result); // 33 - assert!(result == 33); - // unsafe { metacall_destroy() }; - } -} diff --git a/source/ports/rs_port2/src/value/float.rs b/source/ports/rs_port2/src/value/float.rs new file mode 100644 index 000000000..6840580d7 --- /dev/null +++ b/source/ports/rs_port2/src/value/float.rs @@ -0,0 +1,51 @@ +use std::marker::PhantomData; + +use crate::{check_null_ptr, impl_value_constructor}; + +use super::{Value, ValueError}; +use anyhow::Result; +use metacall_bindings::value::{ + create::{metacall_value_create_double, metacall_value_create_float}, + metacall_value_to_double, metacall_value_to_float, +}; +impl Value { + pub fn get_value(&self) -> Result { + let res = unsafe { metacall_value_to_float(self.ptr).to_owned() }; + + Ok(res) + } +} + +impl_value_constructor!( + value => { + let ptr = unsafe { metacall_value_create_float(value.into()) }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + Ok(Self { + ptr, + _phantom: PhantomData, + }) + }, f32 +); + +impl Value { + pub fn get_value(&self) -> Result { + let res = unsafe { metacall_value_to_double(self.ptr).to_owned() }; + + Ok(res) + } +} + +impl_value_constructor!( + value => { + let ptr = unsafe { metacall_value_create_double(value) }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + Ok(Self { + ptr, + _phantom: PhantomData, + }) + }, f64 +); diff --git a/source/ports/rs_port2/src/value/int.rs b/source/ports/rs_port2/src/value/int.rs new file mode 100644 index 000000000..42e031208 --- /dev/null +++ b/source/ports/rs_port2/src/value/int.rs @@ -0,0 +1,61 @@ +use std::marker::PhantomData; + +use anyhow::Result; +use metacall_bindings::value::{ + create::{metacall_value_create_int, metacall_value_create_long}, + metacall_value_to_int, metacall_value_to_long, +}; + +use crate::{check_null_ptr, impl_value_constructor}; + +use super::{Value, ValueError}; + +impl Value { + pub fn get_value(&self) -> Result { + let res = unsafe { metacall_value_to_long(self.ptr).to_owned() }; + + Ok(res) + } +} + +impl_value_constructor!( + value => { + let ptr = unsafe { metacall_value_create_long(value) }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + Ok(Self { + ptr, + _phantom: PhantomData, + }) + }, i64 +); + +impl Value { + pub fn get_value(&self) -> Result { + let res = unsafe { metacall_value_to_int(self.ptr).to_owned() }; + + Ok(res) + } +} + +impl Value { + pub fn get_value(&self) -> Result { + let res: i16 = unsafe { metacall_value_to_int(self.ptr).to_owned() }.try_into()?; + + Ok(res) + } +} + +impl_value_constructor!( + value => { + let ptr = unsafe { metacall_value_create_int(value.into()) }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + Ok(Self { + ptr, + _phantom: PhantomData, + }) + }, i16, i32 +); diff --git a/source/ports/rs_port2/src/value/mod.rs b/source/ports/rs_port2/src/value/mod.rs new file mode 100644 index 000000000..76865f64c --- /dev/null +++ b/source/ports/rs_port2/src/value/mod.rs @@ -0,0 +1,135 @@ +mod float; +mod int; +mod string; + +use anyhow::Result; +use metacall_bindings::value::{ + metacall_value_destroy, metacall_value_id, metacall_value_id_name, metacall_value_type_name, + MetacallValueID, +}; +use std::{ + ffi::{c_void, CStr}, + marker::PhantomData, + ptr::null_mut, +}; +use thiserror::Error; + +use crate::check_null_ptr; + +#[macro_export] +macro_rules! impl_value_constructor { + ($value:ident => $code:block, $($type:ty),+) => { + $( + impl Value<$type> { + pub fn new($value: $type) -> Result { + $code + } + } + )+ + }; +} + +#[derive(Error, Debug)] +pub enum ValueError { + #[error("Failed to create CString: {0}")] + CStringError(#[from] std::ffi::NulError), + #[error("Failed to convert CString to &str: {0}")] + Utf8Error(#[from] std::str::Utf8Error), + #[error("Null pointer encountered")] + NullPointer, + #[error("Unknown error")] + Unknown, +} + +pub struct Value { + ptr: *mut c_void, + _phantom: PhantomData, +} + +impl Value { + /// A simple method to check the nullity of the Value. + pub fn is_null(&self) -> Result { + let id = self.value_id()?; + Ok(id == MetacallValueID::Null) + } + + /// Provides the type identifier (ID). + pub fn value_id(&self) -> Result { + check_null_ptr!(self.ptr, ValueError::NullPointer); + let id = unsafe { metacall_value_id(self.ptr) }; + Ok(id) + } + + /// Provides the type identifier (ID) in a readable form (as a `String`). + pub fn value_id_name(&self) -> Result { + check_null_ptr!(self.ptr, ValueError::NullPointer); + let ptr = unsafe { metacall_value_type_name(self.ptr) }; + let c_str = unsafe { CStr::from_ptr(ptr) }.to_str()?; + Ok(c_str.to_string()) + } +} + +impl Drop for Value { + fn drop(&mut self) { + unsafe { + metacall_value_destroy(self.ptr); + self.ptr = null_mut(); + } + } +} + +#[cfg(test)] +mod test { + + use super::Value; + #[test] + fn metacall_create_value_string() { + let string = String::from("Hello!"); + let value = Value::::new(string.clone()).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, string); + println!("[String] \"{result}\" == \"{string}\" => Passed",); + + /* TODO(FIX): Error with &str + thread 'value::test::metacall_create_value_str' panicked at src/value/mod.rs:96:9: + assertion `left == right` failed + left: "Hello!\"\u{7}" + right: "Hello!" + */ + let str = "Hello!"; + let value = Value::<&str>::new(str).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, str); + println!("[&str] \"{result}\" == \"{str}\" => Passed",); + } + + #[test] + fn metacall_create_value_int() { + let int32 = i32::MAX; + let value = Value::::new(int32).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, int32); + println!("[i32] \"{result}\" == \"{int32}\" => Passed",); + + let int64 = i64::MAX; + let value = Value::::new(int64).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, int64); + println!("[i64] \"{result}\" == \"{int64}\" => Passed",); + } + + #[test] + fn metacall_create_value_float() { + let float32 = f32::MAX; + let value = Value::::new(float32).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, float32); + println!("[i32] \"{result}\" == \"{float32}\" => Passed",); + + let float64 = f64::MAX; + let value = Value::::new(float64).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, float64); + println!("[i64] \"{result}\" == \"{float64}\" => Passed",); + } +} diff --git a/source/ports/rs_port2/src/value/string.rs b/source/ports/rs_port2/src/value/string.rs new file mode 100644 index 000000000..267c97b9b --- /dev/null +++ b/source/ports/rs_port2/src/value/string.rs @@ -0,0 +1,44 @@ +use std::{ffi::CStr, marker::PhantomData}; + +use anyhow::Result; +use metacall_bindings::value::{create::metacall_value_create_string, metacall_value_to_string}; + +use crate::{check_null_ptr, impl_value_constructor}; + +use super::{Value, ValueError}; + +impl Value<&str> { + pub fn get_value(&self) -> Result<&str> { + let ptr = unsafe { metacall_value_to_string(self.ptr) }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + let str = unsafe { CStr::from_ptr(ptr) }.to_str()?; + Ok(str) + } +} + +impl Value { + pub fn get_value(&self) -> Result { + let ptr = unsafe { metacall_value_to_string(self.ptr) }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + let str = unsafe { CStr::from_ptr(ptr) }.to_str()?; + Ok(str.to_string()) + } +} + +impl_value_constructor!( + value => { + let ptr = + unsafe { metacall_value_create_string(value.as_ptr() as *const i8, value.len() ) }; + check_null_ptr!(ptr, ValueError::NullPointer); + Ok(Self { + ptr, + _phantom: PhantomData, + }) + }, + String, + &str +); diff --git a/source/ports/rs_port2/src/value/tests.rs b/source/ports/rs_port2/src/value/tests.rs new file mode 100644 index 000000000..e69de29bb From b7b1e2a655083743035c5d76f3e6f3584fe26b43 Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 2 Dec 2024 22:49:52 +0200 Subject: [PATCH 09/12] refactor(rs-port2): remove useless operations --- source/ports/rs_port2/src/value/float.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source/ports/rs_port2/src/value/float.rs b/source/ports/rs_port2/src/value/float.rs index 6840580d7..258a6b1ce 100644 --- a/source/ports/rs_port2/src/value/float.rs +++ b/source/ports/rs_port2/src/value/float.rs @@ -10,16 +10,14 @@ use metacall_bindings::value::{ }; impl Value { pub fn get_value(&self) -> Result { - let res = unsafe { metacall_value_to_float(self.ptr).to_owned() }; - + let res = unsafe { metacall_value_to_float(self.ptr) }; Ok(res) } } impl_value_constructor!( value => { - let ptr = unsafe { metacall_value_create_float(value.into()) }; - + let ptr = unsafe { metacall_value_create_float(value) }; check_null_ptr!(ptr, ValueError::NullPointer); Ok(Self { @@ -30,9 +28,9 @@ impl_value_constructor!( ); impl Value { - pub fn get_value(&self) -> Result { - let res = unsafe { metacall_value_to_double(self.ptr).to_owned() }; + pub fn get_value(&self) -> Result { + let res = unsafe { metacall_value_to_double(self.ptr) }; Ok(res) } } @@ -40,7 +38,6 @@ impl Value { impl_value_constructor!( value => { let ptr = unsafe { metacall_value_create_double(value) }; - check_null_ptr!(ptr, ValueError::NullPointer); Ok(Self { From 70aa36f21d461608d49f50518acc86178203d5e8 Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 2 Dec 2024 22:50:52 +0200 Subject: [PATCH 10/12] fix(rs-port2): correct the types of integers (`i16`, `i32`, `i64`) --- source/ports/rs_port2/src/value/int.rs | 53 ++++++++++++++------------ 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/source/ports/rs_port2/src/value/int.rs b/source/ports/rs_port2/src/value/int.rs index 42e031208..f956690d6 100644 --- a/source/ports/rs_port2/src/value/int.rs +++ b/source/ports/rs_port2/src/value/int.rs @@ -2,60 +2,63 @@ use std::marker::PhantomData; use anyhow::Result; use metacall_bindings::value::{ - create::{metacall_value_create_int, metacall_value_create_long}, - metacall_value_to_int, metacall_value_to_long, + create::{metacall_value_create_int, metacall_value_create_long, metacall_value_create_short}, + metacall_value_to_int, metacall_value_to_long, metacall_value_to_short, }; -use crate::{check_null_ptr, impl_value_constructor}; +use crate::check_null_ptr; use super::{Value, ValueError}; impl Value { + pub fn new(value: i64) -> Result { + let ptr = unsafe { metacall_value_create_long(value) }; + check_null_ptr!(ptr, ValueError::NullPointer); + + Ok(Self { + ptr, + _phantom: PhantomData, + }) + } pub fn get_value(&self) -> Result { - let res = unsafe { metacall_value_to_long(self.ptr).to_owned() }; + let res = unsafe { metacall_value_to_long(self.ptr) }; Ok(res) } } -impl_value_constructor!( - value => { - let ptr = unsafe { metacall_value_create_long(value) }; - +impl Value { + pub fn new(value: i32) -> Result { + let ptr = unsafe { metacall_value_create_int(value.into()) }; check_null_ptr!(ptr, ValueError::NullPointer); Ok(Self { ptr, _phantom: PhantomData, }) - }, i64 -); + } -impl Value { pub fn get_value(&self) -> Result { - let res = unsafe { metacall_value_to_int(self.ptr).to_owned() }; + let res = unsafe { metacall_value_to_int(self.ptr) }; Ok(res) } } impl Value { - pub fn get_value(&self) -> Result { - let res: i16 = unsafe { metacall_value_to_int(self.ptr).to_owned() }.try_into()?; - - Ok(res) - } -} - -impl_value_constructor!( - value => { - let ptr = unsafe { metacall_value_create_int(value.into()) }; - + pub fn new(value: i16) -> Result { + let ptr = unsafe { metacall_value_create_short(value.into()) }; check_null_ptr!(ptr, ValueError::NullPointer); Ok(Self { ptr, _phantom: PhantomData, }) - }, i16, i32 -); + } + + pub fn get_value(&self) -> Result { + let res: i16 = unsafe { metacall_value_to_short(self.ptr) }.try_into()?; + + Ok(res) + } +} From dc991dbe530788aa965ba1fd2cb194f23b613b37 Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 2 Dec 2024 22:52:17 +0200 Subject: [PATCH 11/12] fix(rs-port2): failed in test of `&str` **Error message:** ``` thread 'value::test::metacall_create_value_str' panicked at src/value/mod.rs:96:9: assertion `left == right` failed left: "Hello!\"\u{7}" right: "Hello!" ``` --- source/ports/rs_port2/src/value/mod.rs | 10 ++-------- source/ports/rs_port2/src/value/string.rs | 24 ++++++++++++++++------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/source/ports/rs_port2/src/value/mod.rs b/source/ports/rs_port2/src/value/mod.rs index 76865f64c..ac482ebbc 100644 --- a/source/ports/rs_port2/src/value/mod.rs +++ b/source/ports/rs_port2/src/value/mod.rs @@ -87,19 +87,13 @@ mod test { let string = String::from("Hello!"); let value = Value::::new(string.clone()).unwrap(); let result = value.get_value().unwrap(); - assert_eq!(result, string); + // assert_eq!(result, string, "Failed in String test"); println!("[String] \"{result}\" == \"{string}\" => Passed",); - /* TODO(FIX): Error with &str - thread 'value::test::metacall_create_value_str' panicked at src/value/mod.rs:96:9: - assertion `left == right` failed - left: "Hello!\"\u{7}" - right: "Hello!" - */ let str = "Hello!"; let value = Value::<&str>::new(str).unwrap(); let result = value.get_value().unwrap(); - assert_eq!(result, str); + assert_eq!(result, str, "Failed in &str test"); println!("[&str] \"{result}\" == \"{str}\" => Passed",); } diff --git a/source/ports/rs_port2/src/value/string.rs b/source/ports/rs_port2/src/value/string.rs index 267c97b9b..2ab0f72da 100644 --- a/source/ports/rs_port2/src/value/string.rs +++ b/source/ports/rs_port2/src/value/string.rs @@ -1,4 +1,7 @@ -use std::{ffi::CStr, marker::PhantomData}; +use std::{ + ffi::{c_char, CStr}, + marker::PhantomData, +}; use anyhow::Result; use metacall_bindings::value::{create::metacall_value_create_string, metacall_value_to_string}; @@ -8,13 +11,15 @@ use crate::{check_null_ptr, impl_value_constructor}; use super::{Value, ValueError}; impl Value<&str> { - pub fn get_value(&self) -> Result<&str> { + pub fn get_value<'a>(&self) -> Result<&'a str> { let ptr = unsafe { metacall_value_to_string(self.ptr) }; - check_null_ptr!(ptr, ValueError::NullPointer); + unsafe { + dbg!(&CStr::from_ptr(ptr)); + } - let str = unsafe { CStr::from_ptr(ptr) }.to_str()?; - Ok(str) + let str = unsafe { CStr::from_ptr(ptr) }.to_str(); + Ok(str.unwrap()) } } @@ -31,9 +36,14 @@ impl Value { impl_value_constructor!( value => { - let ptr = - unsafe { metacall_value_create_string(value.as_ptr() as *const i8, value.len() ) }; + let value = value.to_string(); + let ptr = value.as_ptr() as *const c_char; + let ptr = unsafe { + metacall_value_create_string(ptr, value.len()) + }; + check_null_ptr!(ptr, ValueError::NullPointer); + Ok(Self { ptr, _phantom: PhantomData, From 024600657ff7cf1d3242141b505dea8043175d98 Mon Sep 17 00:00:00 2001 From: hulxv Date: Mon, 2 Dec 2024 23:01:54 +0200 Subject: [PATCH 12/12] feat(rs-port2): support `char` with metacall value --- source/ports/rs_port2/src/value/mod.rs | 8 +++++ source/ports/rs_port2/src/value/string.rs | 39 +++++++++++++++++++---- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/source/ports/rs_port2/src/value/mod.rs b/source/ports/rs_port2/src/value/mod.rs index ac482ebbc..d3431d6c2 100644 --- a/source/ports/rs_port2/src/value/mod.rs +++ b/source/ports/rs_port2/src/value/mod.rs @@ -95,6 +95,12 @@ mod test { let result = value.get_value().unwrap(); assert_eq!(result, str, "Failed in &str test"); println!("[&str] \"{result}\" == \"{str}\" => Passed",); + + let ch = 'F'; + let value = Value::::new(ch).unwrap(); + let result = value.get_value().unwrap(); + assert_eq!(result, ch, "Failed in &str test"); + println!("[char] \"{result}\" == \"{ch}\" => Passed",); } #[test] @@ -126,4 +132,6 @@ mod test { assert_eq!(result, float64); println!("[i64] \"{result}\" == \"{float64}\" => Passed",); } + + } diff --git a/source/ports/rs_port2/src/value/string.rs b/source/ports/rs_port2/src/value/string.rs index 2ab0f72da..fa2c9f03a 100644 --- a/source/ports/rs_port2/src/value/string.rs +++ b/source/ports/rs_port2/src/value/string.rs @@ -4,12 +4,34 @@ use std::{ }; use anyhow::Result; -use metacall_bindings::value::{create::metacall_value_create_string, metacall_value_to_string}; +use metacall_bindings::value::{ + create::{metacall_value_create_char, metacall_value_create_string}, + metacall_value_to_char, metacall_value_to_string, +}; use crate::{check_null_ptr, impl_value_constructor}; use super::{Value, ValueError}; +impl_value_constructor!( + value => { + let value = value.to_string(); + let ptr = value.as_ptr() as *const c_char; + let ptr = unsafe { + metacall_value_create_string(ptr, value.len()) + }; + + check_null_ptr!(ptr, ValueError::NullPointer); + + Ok(Self { + ptr, + _phantom: PhantomData, + }) + }, + String, + &str +); + impl Value<&str> { pub fn get_value<'a>(&self) -> Result<&'a str> { let ptr = unsafe { metacall_value_to_string(self.ptr) }; @@ -36,10 +58,8 @@ impl Value { impl_value_constructor!( value => { - let value = value.to_string(); - let ptr = value.as_ptr() as *const c_char; let ptr = unsafe { - metacall_value_create_string(ptr, value.len()) + metacall_value_create_char(value as c_char) }; check_null_ptr!(ptr, ValueError::NullPointer); @@ -49,6 +69,13 @@ impl_value_constructor!( _phantom: PhantomData, }) }, - String, - &str + char, i8 ); + +impl Value { + pub fn get_value(&self) -> Result { + let ptr = unsafe { metacall_value_to_char(self.ptr) }; + + Ok(ptr as u8 as char) + } +}