### Load and Use Plugins in Host Source: https://docs.rs/dynamic-plugin/latest/index.html Example of how the plugin host finds and interacts with loaded plugins. Ensure the plugin directory exists. ```rust fn main() -> dynamic_plugin::Result<()> { let plugins = ExamplePlugin::find_plugins("./plugins")?; for plugin in plugins { plugin.do_a_thing()?; let s = std::ffi::CString::new("Jens").unwrap(); plugin.say_hello(s.as_ptr())?; } Ok(()) } ``` -------------------------------- ### Using `expect` for Environment Variable Retrieval Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Provides an example of using `expect` to retrieve an environment variable, with a recommended message style that explains why the variable is expected to be set. ```Rust let path = std::env::var("IMPORTANT_PATH") .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`"); ``` -------------------------------- ### Safely get Ok value (nightly) Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `into_ok()` method (experimental, nightly-only) returns the contained `Ok` value without panicking. It requires the error type to be `Infallible`. ```Rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### Handling File Metadata Operations with Result Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Illustrates using `and_then` to chain fallible operations like getting file metadata and modified time. Shows how to handle both successful operations and expected errors like `NotFound`. ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` -------------------------------- ### Loading a Static Variable from a Library Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginDynamicLibrary.html Illustrates how to get a pointer to a static variable within a loaded dynamic library using its symbol name. The correct type for the variable must be provided. ```rust unsafe { let awesome_variable: Symbol<*mut f64> = lib.get(b"awesome_variable\0").unwrap(); **awesome_variable = 42.0; }; ``` -------------------------------- ### Unwrap Ok value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Use `unwrap()` to get the contained `Ok` value. Panics if the value is an `Err`. ```Rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### Iterating Over `Ok` Value with `iter` Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Demonstrates how to get an iterator that yields the `Ok` value if present. If the `Result` is `Err`, the iterator yields nothing. ```Rust let x: Result = Ok(7); assert_eq!(x.iter().next(), Some(&7)); let x: Result = Err("nothing!"); assert_eq!(x.iter().next(), None); ``` -------------------------------- ### Getting a Reference to the Ok Value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `as_ref()` method converts a `&Result` into a `Result<&T, &E>`, providing immutable references to the contained values without consuming the original `Result`. ```Rust let x: Result = Ok(2); assert_eq!(x.as_ref(), Ok(&2)); let x: Result = Err("Error"); assert_eq!(x.as_ref(), Err(&"Error")); ``` -------------------------------- ### Unsafe Undefined Behavior Example for Err Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Illustrates the undefined behavior that occurs when `unwrap_err_unchecked` is called on an `Ok` variant of a `Result`. ```rust let x: Result = Ok(2); unsafe { x.unwrap_err_unchecked() }; // Undefined behavior! ``` -------------------------------- ### Mutable Iteration Over `Ok` Value with `iter_mut` Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Shows how to get a mutable iterator that yields a mutable reference to the `Ok` value if present. This allows modifying the `Ok` value through the iterator. ```Rust let mut x: Result = Ok(7); match x.iter_mut().next() { Some(v) => *v = 40, None => {}, } assert_eq!(x, Ok(40)); let mut x: Result = Err("nothing!"); assert_eq!(x.iter_mut().next(), None); ``` -------------------------------- ### Unwrap or return default value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Use `unwrap_or_default()` to get the contained `Ok` value or the default value for the type if it's an `Err`. This is useful for providing fallback values. ```Rust let good_year_from_input = "1909"; let bad_year_from_input = "190blarg"; let good_year = good_year_from_input.parse().unwrap_or_default(); let bad_year = bad_year_from_input.parse().unwrap_or_default(); assert_eq!(1909, good_year); assert_eq!(0, bad_year); ``` -------------------------------- ### Calculating Sum of Results Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Sums up elements in an iterator of Results. If any element is an Err, the operation short-circuits and returns that Err. Otherwise, it returns the Ok sum of all elements. This example demonstrates summing integers, returning an error if a negative element is encountered. ```Rust let f = |&x: &i32| if x < 0 { Err("Negative element found") } else { Ok(x) }; let v = vec![1, 2]; let res: Result = v.iter().map(f).sum(); assert_eq!(res, Ok(3)); ``` ```Rust let v = vec![1, -2]; let res: Result = v.iter().map(f).sum(); assert_eq!(res, Err("Negative element found")); ``` -------------------------------- ### Getting a Mutable Reference to the Value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `as_mut()` method converts a `&mut Result` into a `Result<&mut T, &mut E>`, providing mutable references to the contained values. ```Rust fn mutate(r: &mut Result) { match r.as_mut() { Ok(v) => *v = 42, Err(e) => *e = 0, } } let mut x: Result = Ok(2); mutate(&mut x); assert_eq!(x.unwrap(), 42); let mut x: Result = Err(13); mutate(&mut x); assert_eq!(x.unwrap_err(), 0); ``` -------------------------------- ### Unwrap Err value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Use `unwrap_err()` to get the contained `Err` value. Panics if the value is an `Ok`. ```Rust let x: Result = Ok(2); x.unwrap_err(); // panics with `2` ``` ```Rust let x: Result = Err("emergency failure"); assert_eq!(x.unwrap_err(), "emergency failure"); ``` -------------------------------- ### Loading a Dynamic Library Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginDynamicLibrary.html Demonstrates various valid ways to load a dynamic library using its filename, relative path, or a specific library name. ```rust unsafe { let _ = Library::new("/path/to/awesome.module").unwrap(); let _ = Library::new("../awesome.module").unwrap(); let _ = Library::new("libsomelib.so.1").unwrap(); } ``` -------------------------------- ### Unsafe Undefined Behavior Example Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Illustrates the undefined behavior that occurs when `unwrap_unchecked` is called on an `Err` variant of a `Result`. ```rust let x: Result = Err("emergency failure"); unsafe { x.unwrap_unchecked() }; // Undefined behavior! ``` -------------------------------- ### Implement Plugin Logic (Client) Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/index.html Implement the plugin's functionality using the `plugin_impl!` macro. This macro associates the concrete implementations with the defined plugin interface. ```Rust use std::ffi::CStr; use dynamic_plugin::{libc::c_char, plugin_interface, plugin_impl}; plugin_interface! { extern struct ExamplePlugin { /// Ask the plugin to do a thing fn do_a_thing(); /// Say hello to a person fn say_hello(to: *const c_char) -> bool; } } plugin_impl! { ExamplePlugin, fn do_a_thing() { println!("A thing has been done!"); } fn say_hello(name: *const c_char) -> bool { unsafe { let name = CStr::from_ptr(name); println!("Hello, {}!", name.to_string_lossy()); } true } } ``` -------------------------------- ### Plugin Client Cargo.toml Configuration Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin Configures a Rust library project to build as a C-compatible dynamic library (cdylib) and includes the `dynamic-plugin` client. ```TOML [lib] crate-type = [ "cdylib" ] [dependencies] dynamic-plugin = { version = "x.x.x", features = [ "client" ] } ``` -------------------------------- ### Implement Plugin Logic for Client Source: https://docs.rs/dynamic-plugin/latest/index.html Provides the concrete implementation for the plugin's functions. Uses unsafe blocks for FFI string manipulation. ```rust plugin_impl! { ExamplePlugin, fn do_a_thing() { println!("A thing has been done!"); } fn say_hello(name: *const c_char) -> bool { unsafe { let name = CStr::from_ptr(name); println!("Hello, {}!", name.to_string_lossy()); } true } } ``` -------------------------------- ### Library::new Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginDynamicLibrary.html Finds and loads a dynamic library. The filename can be a library name, an absolute path, or a relative path. This function is unsafe and requires careful handling of initialization and termination routines. ```APIDOC ## unsafe fn new

(filename: P) -> Result ### Description Find and load a dynamic library. The `filename` argument may be either: * A library filename; * The absolute path to the library; * A relative (to the current working directory) path to the library. ### Safety When a library is loaded, initialisation routines contained within it are executed. For the purposes of safety, the execution of these routines is conceptually the same calling an unknown foreign function and may impose arbitrary requirements on the caller for the call to be sound. Additionally, the callers of this function must also ensure that execution of the termination routines contained within the library is safe as well. These routines may be executed when the library is unloaded. ### Platform-specific behaviour When a plain library filename is supplied, the locations in which the library is searched are platform specific and cannot be adjusted in a portable manner. See the documentation for the platform specific `os::unix::Library::new` and `os::windows::Library::new` methods for further information on library lookup behaviour. If the `filename` specifies a library filename without a path and with the extension omitted, the `.dll` extension is implicitly added on Windows. ### Tips Distributing your dynamic libraries under a filename common to all platforms (e.g. `awesome.module`) allows you to avoid code which has to account for platform’s conventional library filenames. Strive to specify an absolute or at least a relative path to your library, unless system-wide libraries are being loaded. Platform-dependent library search locations combined with various quirks related to path-less filenames may cause flakiness in programs. ### Examples ``` // Any of the following are valid. unsafe { let _ = Library::new("/path/to/awesome.module").unwrap(); let _ = Library::new("../awesome.module").unwrap(); let _ = Library::new("libsomelib.so.1").unwrap(); } ``` ``` -------------------------------- ### Expect Err value with custom panic message Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Use `expect_err()` to get the contained `Err` value. Panics with a custom message if the value is an `Ok`. ```Rust let x: Result = Ok(10); x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` ``` -------------------------------- ### into_ok Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the contained Ok value, never panics. This is an experimental API. ```APIDOC ## into_ok ### Description Returns the contained `Ok` value, but never panics. This method is known to never panic on the result types it is implemented for, making it a maintainability safeguard. ### Method `into_ok()` ### Parameters None ### Response #### Success Response (T) Returns the contained `Ok` value of type `T`. ### Note This is a nightly-only experimental API. ### Example ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` ``` -------------------------------- ### Safely get Err value (nightly) Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `into_err()` method (experimental, nightly-only) returns the contained `Err` value without panicking. It requires the Ok type to be `Infallible`. ```Rust fn only_bad_news() -> Result { Err("Oops, it failed".into()) } let error: String = only_bad_news().into_err(); println!("{error}"); ``` -------------------------------- ### Loading a Function from a Library Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginDynamicLibrary.html Shows how to retrieve a function pointer from a loaded dynamic library by its symbol name. Ensure the correct function signature is specified. ```rust unsafe { let awesome_function: Symbol f64> = lib.get(b"awesome_function\0").unwrap(); awesome_function(0.42); } ``` -------------------------------- ### Define Plugin Interface (Client) Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/index.html Define the plugin interface within the client project using the `plugin_interface!` macro. This ensures the client adheres to the expected interface. ```Rust use std::ffi::CStr; use dynamic_plugin::{libc::c_char, plugin_interface}; plugin_interface! { extern struct ExamplePlugin { /// Ask the plugin to do a thing fn do_a_thing(); /// Say hello to a person fn say_hello(to: *const c_char) -> bool; } } ``` -------------------------------- ### Implement Plugin Interface in Client Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin Implements the plugin interface defined by the host using the `plugin_impl!` macro. Requires `unsafe` blocks for CStr manipulation. ```Rust use std::ffi::CStr; use dynamic_plugin::{libc::c_char, plugin_interface, plugin_impl}; plugin_interface! { extern struct ExamplePlugin { /// Ask the plugin to do a thing fn do_a_thing(); /// Say hello to a person fn say_hello(name: *const c_char) -> bool; } } plugin_impl! { ExamplePlugin, fn do_a_thing() { println!("A thing has been done!"); } fn say_hello(name: *const c_char) -> bool { unsafe { let name = CStr::from_ptr(name); println!("Hello, {}!", name.to_string_lossy()); } true } } ``` -------------------------------- ### or Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the `Ok` value of self if it is `Ok`, otherwise returns the provided `res` Result. Arguments are eagerly evaluated. ```APIDOC ## pub fn or(self, res: Result) -> Result Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`. Arguments passed to `or` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `or_else`, which is lazily evaluated. ##### §Examples ```rust let x: Result = Ok(2); let y: Result = Err("late error"); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("early error"); let y: Result = Ok(2); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("not a 2"); let y: Result = Err("late error"); assert_eq!(x.or(y), Err("late error")); let x: Result = Ok(2); let y: Result = Ok(100); assert_eq!(x.or(y), Ok(2)); ``` ``` -------------------------------- ### unwrap_or Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the contained `Ok` value or a provided default. Arguments are eagerly evaluated. ```APIDOC ## pub fn unwrap_or(self, default: T) -> T Returns the contained `Ok` value or a provided default. Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing the result of a function call, it is recommended to use `unwrap_or_else`, which is lazily evaluated. ##### §Examples ```rust let default = 2; let x: Result = Ok(9); assert_eq!(x.unwrap_or(default), 9); let x: Result = Err("error"); assert_eq!(x.unwrap_or(default), default); ``` ``` -------------------------------- ### ok() Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Converts a Result into an Option, consuming the Result and discarding the error if present. ```APIDOC ## pub fn ok(self) -> Option ### Description Converts from `Result` to `Option`. Consumes `self`, returning `Some(T)` if the result was `Ok`, and `None` if it was `Err`. ### Method `self.ok()` ### Parameters None ### Response #### Success Response (Some(T)) - Returns `Some(T)` if the original Result was `Ok(T)`. #### Error Response (None) - Returns `None` if the original Result was `Err(E)`. ### Request Example ```rust let x: Result = Ok(2); assert_eq!(x.ok(), Some(2)); let x: Result = Err("Nothing here"); assert_eq!(x.ok(), None); ``` ``` -------------------------------- ### Using or to Provide a Default Error Value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Demonstrates the `or` method, which returns the `Ok` value of `self` if it's `Ok`, otherwise returns the provided `Result`. Note that arguments to `or` are eagerly evaluated. ```rust let x: Result = Ok(2); let y: Result = Err("late error"); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("early error"); let y: Result = Ok(2); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("not a 2"); let y: Result = Err("late error"); assert_eq!(x.or(y), Err("late error")); let x: Result = Ok(2); let y: Result = Ok(100); assert_eq!(x.or(y), Ok(2)); ``` -------------------------------- ### Inspecting `Ok` Values with `inspect` Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Shows how to perform a side effect, like printing, when the Result is `Ok` without altering the value. The original Result is returned. ```Rust let x: u8 = "4" .parse::() .inspect(|x| println!("original: {x}")) .map(|x| x.pow(3)) .expect("failed to parse number"); ``` -------------------------------- ### Converting Result to Option with Ok Value Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `ok()` method converts a `Result` into an `Option`. It consumes the `Result` and returns `Some(T)` if it was `Ok`, otherwise `None`. ```Rust let x: Result = Ok(2); assert_eq!(x.ok(), Some(2)); let x: Result = Err("Nothing here"); assert_eq!(x.ok(), None); ``` -------------------------------- ### Wrapping Raw Symbol into PluginLibrarySymbol Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginLibrarySymbol.html Wraps an OS-specific symbol into a safe PluginLibrarySymbol. This requires a reference to the library the symbol was loaded from to maintain lifetime associations. The library reference must be the exact one the symbol originated from. ```rust unsafe { let lib = Library::new("/path/to/awesome.module").unwrap(); let symbol: Symbol<*mut u32> = lib.get(b"symbol\0").unwrap(); let symbol = symbol.into_raw(); let symbol = Symbol::from_raw(symbol, &lib); } ``` -------------------------------- ### Unwrapping `Result` with `expect` and Custom Message Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Illustrates using `expect` to retrieve the `Ok` value, panicking with a custom message if the `Result` is `Err`. This method is generally discouraged in favor of safer error handling. ```Rust let x: Result = Err("emergency failure"); x.expect("Testing expect"); // panics with `Testing expect: emergency failure` ``` -------------------------------- ### Chaining Fallible Operations with and_then Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Demonstrates chaining operations that return Result using `and_then`. Useful for sequential fallible computations where the next step depends on the success of the previous one. Handles potential overflows and errors gracefully. ```rust fn sq_then_to_string(x: u32) -> Result { x.checked_mul(x).map(|sq| sq.to_string()).ok_or("overflowed") } assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string())); assert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err("overflowed")); assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number")); ``` -------------------------------- ### as_ref() Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Converts a reference to a Result into a Result<&T, &E>, leaving the original Result unchanged. ```APIDOC ## pub const fn as_ref(&self) -> Result<&T, &E> ### Description Converts from `&Result` to `Result<&T, &E>`. Produces a new `Result`, containing a reference into the original, leaving the original in place. ### Method `self.as_ref()` ### Parameters None ### Response #### Success Response (Ok(&T)) - Returns `Ok(&T)` if the original Result was `Ok(T)`. #### Error Response (Err(&E)) - Returns `Err(&E)` if the original Result was `Err(E)`. ### Request Example ```rust let x: Result = Ok(2); assert_eq!(x.as_ref(), Ok(&2)); let x: Result = Err("Error"); assert_eq!(x.as_ref(), Err(&"Error")); ``` ``` -------------------------------- ### unwrap Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the contained `Ok` value, consuming the `self` value. Panics if the value is an `Err`. ```APIDOC ## pub fn unwrap(self) -> T where E: Debug ### Description Returns the contained `Ok` value, consuming the `self` value. Because this function may panic, its use is generally discouraged. Panics are meant for unrecoverable errors, and may abort the entire program. Instead, prefer to use the `?` (try) operator, or pattern matching to handle the `Err` case explicitly, or call `unwrap_or`, `unwrap_or_else`, or `unwrap_or_default`. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None provided. ### Response #### Success Response (200) The contained `Ok` value. #### Response Example None provided. ### Panics Panics if the value is an `Err`. ``` -------------------------------- ### Converting `Result` to `Result<&str, &u32>` with `as_deref` Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Demonstrates using `as_deref` to convert a `Result` containing a type that implements `Deref` into a `Result` containing a reference to the dereferenced type. This is useful for borrowing the inner value without consuming the original `Result`. ```Rust let x: Result = Ok("hello".to_string()); let y: Result<&str, &u32> = Ok("hello"); assert_eq!(x.as_deref(), y); let x: Result = Err(42); let y: Result<&str, &u32> = Err(&42); assert_eq!(x.as_deref(), y); ``` -------------------------------- ### Dynamic Plugin Library Re-exports Source: https://docs.rs/dynamic-plugin/latest/src/dynamic_plugin/lib.rs.html This snippet shows the re-exports of macros and libraries used by the dynamic-plugin crate, such as dynamic_plugin_macros, const_format, and libloading. ```rust #![deny(missing_docs)] #![warn(clippy::pedantic)] #![doc = include_str!("../README.md")] // Re-export macros pub use dynamic_plugin_macros::*; pub use const_format::concatcp as const_concat; // Re-export libloading library pub use libloading::Library as PluginDynamicLibrary; pub use libloading::Symbol as PluginLibrarySymbol; /// Re-exported libc types for convenience. pub use libc; ``` -------------------------------- ### expect Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the contained `Ok` value, consuming the `self` value. Panics if the value is an `Err`. ```APIDOC ## pub fn expect(self, msg: &str) -> T where E: Debug ### Description Returns the contained `Ok` value, consuming the `self` value. Because this function may panic, its use is generally discouraged. Instead, prefer to use pattern matching and handle the `Err` case explicitly, or call `unwrap_or`, `unwrap_or_else`, or `unwrap_or_default`. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let x: Result = Err("emergency failure"); x.expect("Testing expect"); // panics with `Testing expect: emergency failure` ``` ### Response #### Success Response (200) The contained `Ok` value. #### Response Example None provided. ### Panics Panics if the value is an `Err`, with a panic message including the passed message, and the content of the `Err`. ``` -------------------------------- ### Define Plugin Interface for Client Source: https://docs.rs/dynamic-plugin/latest/index.html Defines the external struct for the plugin interface that the client will implement. This mirrors the host's interface definition. ```rust use std::ffi::CStr; use dynamic_plugin::{libc::c_char, plugin_interface, plugin_impl}; plugin_interface! { extern struct ExamplePlugin { /// Ask the plugin to do a thing fn do_a_thing(); /// Say hello to a person fn say_hello(to: *const c_char) -> bool; } } ``` -------------------------------- ### map_or_default() Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a Result to a U by applying a function to the Ok value or returning the default value for U if Err. ```APIDOC ## pub const fn map_or_default(self, f: F) -> U where F: FnOnce(T) -> U, U: Default ### Description Maps a `Result` to a `U` by applying function `f` to the contained value if the result is `Ok`, otherwise if `Err`, returns the default value for the type `U`. ### Method `self.map_or_default(f)` ### Parameters - **f**: A closure that takes the `Ok` value and returns a `U`. ### Response - Returns the result of the closure `f` if the Result is `Ok`, otherwise returns the default value of type `U`. ### Request Example ```rust #![feature(result_option_map_or_default)] let x: Result<_, &str> = Ok("foo"); let y: Result<&str, _> = Err("bar"); assert_eq!(x.map_or_default(|x| x.len()), 3); assert_eq!(y.map_or_default(|y| y.len()), 0); ``` ``` -------------------------------- ### Define Plugin Interface for Host Source: https://docs.rs/dynamic-plugin/latest/index.html Defines the external trait for the plugin interface that the host will use. Requires C-compatible data types for FFI. ```rust use dynamic_plugin::{libc::c_char, plugin_interface}; plugin_interface! { extern trait ExamplePlugin { /// Ask the plugin to do a thing fn do_a_thing(); /// Say hello to a person fn say_hello(to: *const c_char) -> bool; } } ``` -------------------------------- ### Lifting Option from PluginLibrarySymbol Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginLibrarySymbol.html Lifts an Option out of a PluginLibrarySymbol, converting a Symbol> into an Option>. This is useful when a symbol might represent a null pointer or an optional value. ```rust unsafe { let lib = Library::new("/path/to/awesome.module").unwrap(); let symbol: Symbol> = lib.get(b"symbol\0").unwrap(); let symbol: Symbol<*mut u32> = symbol.lift_option().expect("static is not null"); } ``` -------------------------------- ### Copying Result<&mut T, E> Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a `Result<&mut T, E>` to a `Result` by copying the `Ok` value. Requires `T` to implement `Copy`. ```rust let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let copied = x.copied(); assert_eq!(copied, Ok(12)); ``` -------------------------------- ### Cloning Result<&mut T, E> Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a `Result<&mut T, E>` to a `Result` by cloning the `Ok` value. Requires `T` to implement `Clone`. ```rust let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` -------------------------------- ### unwrap Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the contained Ok value or panics if the value is an Err. The panic message is provided by the Err's value. ```APIDOC ## unwrap ### Description Returns the contained `Ok` value or panics if the value is an `Err`. The panic message is provided by the `Err`'s value. ### Method `unwrap()` ### Parameters None ### Response #### Success Response (T) Returns the contained `Ok` value of type `T`. #### Response Example ```rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` ### Panics Panics if the value is an `Err`, with a panic message provided by the `Err`’s value. ### Example ```rust let x: Result = Err("emergency failure"); x.unwrap(); // panics with `emergency failure` ``` ``` -------------------------------- ### Define Plugin Interface Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/macro.plugin_interface.html Use this macro to declare the external trait for your plugin, specifying the methods it should expose. Ensure that the plugin implementation provides these methods. ```Rust plugin_interface! { extern trait ExamplePlugin { /// Ask the plugin to do a thing fn do_a_thing(); /// Say hello to a person fn say_hello(to: *const c_char) -> bool; } } ``` -------------------------------- ### inspect Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Calls a function with a reference to the contained value if `Ok`. Returns the original result. ```APIDOC ## pub fn inspect(self, f: F) -> Result where F: FnOnce(&T) ### Description Calls a function with a reference to the contained value if `Ok`. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let x: u8 = "4" .parse::() .inspect(|x| println!("original: {x}")) .map(|x| x.pow(3)) .expect("failed to parse number"); ``` ### Response #### Success Response (200) Returns the original result. #### Response Example None provided. ``` -------------------------------- ### as_mut() Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Converts a mutable reference to a Result into a Result<&mut T, &mut E>, allowing in-place modification. ```APIDOC ## pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> ### Description Converts from `&mut Result` to `Result<&mut T, &mut E>`. Produces a new `Result`, containing a mutable reference into the original, leaving the original in place. ### Method `self.as_mut()` ### Parameters None ### Response #### Success Response (Ok(&mut T)) - Returns `Ok(&mut T)` if the original Result was `Ok(T)`. #### Error Response (Err(&mut E)) - Returns `Err(&mut E)` if the original Result was `Err(E)`. ### Request Example ```rust fn mutate(r: &mut Result) { match r.as_mut() { Ok(v) => *v = 42, Err(e) => *e = 0, } } let mut x: Result = Ok(2); mutate(&mut x); assert_eq!(x.unwrap(), 42); let mut x: Result = Err(13); mutate(&mut x); assert_eq!(x.unwrap_err(), 0); ``` ``` -------------------------------- ### Library::get Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/struct.PluginDynamicLibrary.html Retrieves a pointer to a function or static variable from the loaded dynamic library using its symbol name. The symbol name is treated as-is, without mangling. This function is unsafe and requires the caller to specify the correct type for the loaded symbol. ```APIDOC ## unsafe fn get(&self, symbol: &[u8]) -> Result, Error> ### Description Get a pointer to a function or static variable by symbol name. The `symbol` may not contain any null bytes, with the exception of the last byte. Providing a null-terminated `symbol` may help to avoid an allocation. The symbol is interpreted as-is; no mangling is done. This means that symbols like `x::y` are most likely invalid. ### Safety Users of this API must specify the correct type of the function or variable loaded. ### Platform-specific behaviour The implementation of thread-local variables is extremely platform specific and uses of such variables that work on e.g. Linux may have unintended behaviour on other targets. On POSIX implementations where the `dlerror` function is not confirmed to be MT-safe (such as FreeBSD), this function will unconditionally return an error when the underlying `dlsym` call returns a null pointer. There are rare situations where `dlsym` returns a genuine null pointer without it being an error. If loading a null pointer is something you care about, consider using the `os::unix::Library::get_singlethreaded` call. ### Examples Given a loaded library: ``` let lib = unsafe { Library::new("/path/to/awesome.module").unwrap() }; ``` Loading and using a function looks like this: ``` unsafe { let awesome_function: Symbol f64> = lib.get(b"awesome_function\0").unwrap(); awesome_function(0.42); } ``` A static variable may also be loaded and inspected: ``` unsafe { let awesome_variable: Symbol<*mut f64> = lib.get(b"awesome_variable\0").unwrap(); **awesome_variable = 42.0; }; ``` ``` -------------------------------- ### Combine Results with 'and' Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `and()` method returns the second `Result` if the first is `Ok`, otherwise returns the `Err` of the first. Arguments are eagerly evaluated. ```Rust let x: Result = Ok(2); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("late error")); let x: Result = Err("early error"); let y: Result<&str, &str> = Ok("foo"); assert_eq!(x.and(y), Err("early error")); let x: Result = Err("not a 2"); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("not a 2")); let x: Result = Ok(2); let y: Result<&str, &str> = Ok("different result type"); assert_eq!(x.and(y), Ok("different result type")); ``` -------------------------------- ### Copying Result<&T, E> Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a `Result<&T, E>` to a `Result` by copying the `Ok` value. Requires `T` to implement `Copy`. ```rust let val = 12; let x: Result<&i32, i32> = Ok(&val); assert_eq!(x, Ok(&12)); let copied = x.copied(); assert_eq!(copied, Ok(12)); ``` -------------------------------- ### Transposing Result, E> Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Transposes a `Result` containing an `Option` into an `Option` containing a `Result`. `Ok(None)` becomes `None`. ```rust #[derive(Debug, Eq, PartialEq)] struct SomeErr; let x: Result, SomeErr> = Ok(Some(5)); let y: Option> = Some(Ok(5)); assert_eq!(x.transpose(), y); ``` -------------------------------- ### into_err Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns the contained Err value, never panics. This is an experimental API. ```APIDOC ## into_err ### Description Returns the contained `Err` value, but never panics. This method is known to never panic on the result types it is implemented for, making it a maintainability safeguard. ### Method `into_err()` ### Parameters None ### Response #### Success Response (E) Returns the contained `Err` value of type `E`. ### Note This is a nightly-only experimental API. ### Example ```rust fn only_bad_news() -> Result { Err("Oops, it failed".into()) } let error: String = only_bad_news().into_err(); println!("{error}"); ``` ``` -------------------------------- ### as_deref_mut Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Converts from `Result` to `Result<&mut ::Target, &mut E>` by coercing the `Ok` variant via `DerefMut`. ```APIDOC ## pub fn as_deref_mut(&mut self) -> Result<&mut ::Target, &mut E> where T: DerefMut ### Description Converts from `Result` (or `&mut Result`) to `Result<&mut ::Target, &mut E>`. Coerces the `Ok` variant of the original `Result` via `DerefMut` and returns the new `Result`. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let mut s = "HELLO".to_string(); let mut x: Result = Ok("hello".to_string()); let y: Result<&mut str, &mut u32> = Ok(&mut s); assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); let mut i = 42; let mut x: Result = Err(42); let y: Result<&mut str, &mut u32> = Err(&mut i); assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); ``` ### Response #### Success Response (200) Returns a mutable `Result` with a mutable reference to the dereferenced `Ok` value or a mutable reference to the `Err` value. #### Response Example None provided. ``` -------------------------------- ### Cloning Result<&T, E> Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a `Result<&T, E>` to a `Result` by cloning the `Ok` value. Requires `T` to implement `Clone`. ```rust let val = 12; let x: Result<&i32, i32> = Ok(&val); assert_eq!(x, Ok(&12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` -------------------------------- ### Unwrapping Result with a Default Value using unwrap_or Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Demonstrates `unwrap_or`, which returns the contained `Ok` value or a provided default if the `Result` is `Err`. Arguments are eagerly evaluated. ```rust let default = 2; let x: Result = Ok(9); assert_eq!(x.unwrap_or(default), 9); let x: Result = Err("error"); assert_eq!(x.unwrap_or(default), default); ``` -------------------------------- ### and Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns `res` if the result is Ok, otherwise returns the Err value of self. Arguments are eagerly evaluated. ```APIDOC ## and ### Description Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`. Arguments passed to `and` are eagerly evaluated. ### Method `and(self, res: Result) -> Result` ### Parameters * **res** (Result) - Required - The `Result` to return if `self` is `Ok`. ### Response #### Success Response (Result) Returns `res` if `self` is `Ok`, otherwise returns the `Err` value of `self`. ### Example ```rust let x: Result = Ok(2); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("late error")); let x: Result = Err("early error"); let y: Result<&str, &str> = Ok("foo"); assert_eq!(x.and(y), Err("early error")); let x: Result = Err("not a 2"); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("not a 2")); let x: Result = Ok(2); let y: Result<&str, &str> = Ok("different result type"); assert_eq!(x.and(y), Ok("different result type")); ``` ``` -------------------------------- ### static_assert Macro Definition Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/macro.static_assert.html Defines the static_assert macro, which takes an expression and a message. It is used for compile-time assertions within the dynamic-plugin crate. ```rust macro_rules! static_assert { ($exp:expr, $msg:expr) => { ... }; } ``` -------------------------------- ### map_or_else() Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a Result to a U by applying a fallback function for Err or a function for Ok. ```APIDOC ## pub fn map_or_else(self, default: D, f: F) -> U where D: FnOnce(E) -> U, F: FnOnce(T) -> U ### Description Maps a `Result` to `U` by applying fallback function `default` to a contained `Err` value, or function `f` to a contained `Ok` value. This function can be used to unpack a successful result while handling an error. ### Method `self.map_or_else(default, f)` ### Parameters - **default**: A closure that takes the `Err` value and returns a `U`. - **f**: A closure that takes the `Ok` value and returns a `U`. ### Response - Returns the result of the closure `f` if the Result is `Ok`, otherwise returns the result of the closure `default`. ### Request Example ```rust let k = 21; let x : Result<_, &str> = Ok("foo"); assert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 3); let x : Result<&str, _> = Err("bar"); assert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 42); ``` ``` -------------------------------- ### Mapping an Ok Value with a Function Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html The `map()` method applies a function to the contained value in an `Ok` variant, transforming it into a new `Result` type. `Err` variants are left untouched. ```Rust let line = "1\n2\n3\n4\n"; for num in line.lines() ``` ```text ``` ```text ``` -------------------------------- ### Result<&mut T, E>::cloned Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Maps a `Result<&mut T, E>` to a `Result` by cloning the contents of the `Ok` part. This method is available for mutable references and requires `T` to implement `Clone`. ```APIDOC ### impl Result<&mut T, E> #### pub fn cloned(self) -> Result where T: Clone, Maps a `Result<&mut T, E>` to a `Result` by cloning the contents of the `Ok` part. ##### §Examples ``` let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` ``` -------------------------------- ### Result::is_ok_and Source: https://docs.rs/dynamic-plugin/latest/dynamic_plugin/type.Result.html Returns `true` if the result is `Ok` and the contained value satisfies a given predicate. This allows for conditional checks on successful results. ```APIDOC ### impl Result #### pub fn is_ok_and(self, f: F) -> bool where F: FnOnce(T) -> bool, Returns `true` if the result is `Ok` and the value inside of it matches a predicate. ##### §Examples ``` let x: Result = Ok(2); assert_eq!(x.is_ok_and(|x| x > 1), true); let x: Result = Ok(0); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Err("hey"); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Ok("ownership".to_string()); assert_eq!(x.as_ref().is_ok_and(|x| x.len() > 1), true); println!("still alive {:?}", x); ``` ```