### Controlled Reload with State Serialization in Rust Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This example demonstrates how to control library reloads using `BlockReload` to perform pre-reload preparations like state serialization. It prevents reload until the `BlockReload` token is dropped, ensuring safe state management. Dependencies include `hot_lib_reloader`, `tokio`, and `serde`. ```rust use hot_lib_reloader::BlockReload; use std::time::Duration; use tokio::{spawn, sync::mpsc, task::spawn_blocking, time}; #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::State; hot_functions_from_file!("lib/src/lib.rs"); #[lib_change_subscription] pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {} } #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); let (tx, mut rx) = mpsc::channel(1); spawn(async move { loop { let block_reload = spawn_blocking(|| hot_lib::subscribe().wait_for_about_to_reload()) .await .expect("get token"); tx.send(block_reload).await.expect("send token"); } }); let mut state = hot_lib::State { counter: 0 }; loop { tokio::select! { _ = time::sleep(Duration::from_secs(1)) => { hot_lib::do_stuff(&mut state); } Some(block_reload_token) = rx.recv() => { do_reload(block_reload_token, &mut state).await; } } } } async fn do_reload(block_reload_token: BlockReload, state: &mut lib::State) { println!("About to reload lib but first do some long running operation..."); let file = std::fs::File::create("state.json").expect("save file"); state.save(file); time::sleep(Duration::from_secs(1)).await; println!("...now we are ready for reloading..."); drop(block_reload_token); // dropping token allows reload to proceed spawn_blocking(|| hot_lib::subscribe().wait_for_reload()) .await .expect("wait for reload"); println!("...now we have the new library version loaded"); let file = std::fs::File::open("state.json").expect("open file"); *state = lib::State::load(file); } ``` ```rust // lib/src/lib.rs - library with serialization support use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize)] pub struct State { pub counter: usize, } impl State { pub fn load(reader: impl std::io::Read) -> Self { serde_json::from_reader(reader).expect("deserialize") } pub fn save(&self, writer: impl std::io::Write) { serde_json::to_writer(writer, self).expect("serialize state"); } } #[unsafe(no_mangle)] pub fn do_stuff(state: &mut State) { state.counter += 1; println!("doing stuff in iteration {}", state.counter); } ``` -------------------------------- ### Configure Library Directory, Debounce, and Naming Template (Rust) Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This example showcases advanced configuration options for the hot-lib-reloader crate, including specifying the library directory, setting a file watch debounce time in milliseconds, and customizing the loaded library name template. It demonstrates importing all items from the library and manually declaring hot-reloadable function signatures. ```rust #[hot_lib_reloader::hot_module( dylib = "lib", lib_dir = if cfg!(debug_assertions) { "target/debug" } else { "target/release" }, file_watch_debounce = 500, // milliseconds loaded_lib_name_template = "{lib_name}_hot_{pid}_{load_counter}" )] mod hot_lib { pub use lib::*; // Import functions from source file hot_functions_from_file!("lib/src/lib.rs"); // Or manually declare hot-reloadable function signatures #[hot_functions] extern "Rust" { pub fn custom_function(arg: &str) -> u32; } #[lib_change_subscription] pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {} #[lib_version] pub fn version() -> usize {} #[lib_updated] pub fn was_updated() -> bool {} } fn main() { let mut state = hot_lib::State { counter: 0 }; loop { hot_lib::do_stuff(&mut state); let update_blocker = hot_lib::subscribe().wait_for_about_to_reload(); println!("about to reload..."); std::thread::sleep(std::time::Duration::from_secs(1)); drop(update_blocker); hot_lib::subscribe().wait_for_reload(); println!("reloaded at version {} now", hot_lib::version()); } } ``` -------------------------------- ### Flexible State Management with JSON Values in Rust Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This example demonstrates flexible state management using generic JSON values, allowing for free modification of the internal state structure without compatibility issues between reloads. It utilizes `serde_json::Value` for dynamic state representation. Dependencies include `hot_lib_reloader` and `serde`. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::State; hot_functions_from_file!("lib/src/lib.rs"); #[lib_version] pub fn version() -> usize {} #[lib_change_subscription] pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {} } fn main() { let mut state = hot_lib::State::default(); loop { state = hot_lib::step(state); hot_lib::subscribe().wait_for_reload(); state.version = hot_lib::version(); } } ``` ```rust // lib/src/lib.rs - flexible state with serde_json::Value #[derive(Debug, Default)] pub struct State { pub version: usize, pub inner: Box, } #[derive(Default, Debug, serde::Deserialize, serde::Serialize)] struct InnerState { // Modify this structure freely without breaking compatibility } #[unsafe(no_mangle)] pub fn step(state: State) -> State { let State { version, inner } = state; let inner: InnerState = serde_json::from_value(*inner).unwrap_or_default(); println!("version {version}: {inner:?}"); // Modify InnerState layout freely - changes handled via JSON serialization State { version, inner: Box::new(serde_json::to_value(inner).unwrap()), } } ``` -------------------------------- ### Run Library Compilation and Executable Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md These bash commands demonstrate how to concurrently compile the dynamic library and run the main executable. `cargo watch` is used to automatically rebuild the library when changes are detected, and `cargo run` starts the application. This setup facilitates the hot reloading workflow. ```bash # Forwards output, stops all on ctr-c, fails if one command fails parallel --line-buffer --halt now,fail=1 ::: \ "cargo watch -i lib -x run" \ "cargo watch -w lib -x 'build -p lib'" ``` -------------------------------- ### Low-Level Library Management with LibReloader (Rust) Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This snippet demonstrates the low-level usage of the `LibReloader` from the `hot-lib-reloader` crate. It provides direct control over library loading and symbol resolution, which is useful when the macro abstractions are insufficient. The code manually creates a `LibReloader` instance, gets symbols from the dynamic library, and checks for updates. ```rust use hot_lib_reloader::{LibReloader, HotReloaderError}; use std::time::Duration; use std::path::Path; fn main() -> Result<(), HotReloaderError> { let lib_dir = Path::new("target/debug"); let lib_name = "lib"; let debounce = Some(Duration::from_millis(500)); let name_template = Some("{lib_name}_hot_{load_counter}".to_string()); let mut reloader = LibReloader::new( lib_dir, lib_name, debounce, name_template, )?; loop { // Get symbol from library unsafe { let do_stuff: libloading::Symbol = reloader.get_symbol(b"do_stuff\0")?; let mut state = State { counter: 0 }; do_stuff(&mut state); } // Check for updates and reload if necessary if reloader.update()? { LibReloader::log_info("Library was reloaded"); } std::thread::sleep(Duration::from_secs(1)); } } struct State { counter: usize, } ``` -------------------------------- ### Workspace Cargo.toml Configuration Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This TOML snippet configures a Rust workspace, defining a root package named 'bin' and including a library crate named 'lib'. It specifies the dependency on the `hot-lib-reloader` crate, which is essential for enabling hot-reloading functionality. The workspace setup allows for managing both the executable and the reloadable library within a single project structure. ```toml [workspace] resolver = "2" members = ["lib"] [package] name = "bin" version = "0.1.0" edition = "2024" [dependencies] hot-lib-reloader = "0.8" lib = { path = "lib" } ``` -------------------------------- ### Setup Hot Module with #[hot_module] Macro in Rust Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt Sets up a hot-reloadable module using the #[hot_module] macro. It defines a module 'hot_lib' that imports types and functions from a dynamic library named 'lib'. Functions marked with #[unsafe(no_mangle)] in the library become automatically reloadable. The main function initializes logging and enters a loop that calls the 'do_stuff' function from the hot-reloaded library. ```rust // main.rs - executable #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::State; hot_functions_from_file!("lib/src/lib.rs"); } fn main() { env_logger::init(); // Use RUST_LOG=hot_lib_reloader=trace for debug logs let mut state = hot_lib::State { counter: 0 }; loop { hot_lib::do_stuff(&mut state); std::thread::sleep(std::time::Duration::from_secs(1)); } } ``` ```rust // lib/src/lib.rs - hot-reloadable library pub struct State { pub counter: usize, } #[unsafe(no_mangle)] pub fn do_stuff(state: &mut State) { state.counter += 1; println!("doing stuff in iteration {}", state.counter); } ``` ```toml # lib/Cargo.toml [package] name = "lib" version = "0.1.0" edition = "2024" [lib] crate-type = ["rlib", "dylib"] ``` -------------------------------- ### Debugging hot-lib-reloader with cargo expand and Logging Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md For debugging compilation errors related to `hot_module`, `cargo expand` can be used to inspect the generated code. The `hot-lib-reloader` crate logs its internal operations using the `log` crate. You can enable detailed logs by setting the `RUST_LOG` environment variable, for example, `RUST_LOG=hot_lib_reloader=trace`, when using a logging framework like `env_logger`. ```bash RUST_LOG=hot_lib_reloader=trace cargo run ``` -------------------------------- ### Subscribe to Reload Events with LibReloadObserver in Rust Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt Demonstrates subscribing to library reload events using the #[lib_change_subscription] attribute and LibReloadObserver. The main function initializes state and an observer. The loop calls a 'step' function and then blocks on the observer's 'wait_for_reload()' method, ensuring subsequent actions use the newly loaded library version. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::State; hot_functions_from_file!("lib/src/lib.rs"); #[lib_change_subscription] pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {} } fn main() { let mut state = hot_lib::State { counter: 0 }; let lib_observer = hot_lib::subscribe(); loop { hot_lib::step(&mut state); // blocks until lib was reloaded lib_observer.wait_for_reload(); println!("Library was reloaded, continuing with new version"); } } ``` -------------------------------- ### Main Application Loop for Hot Reloading Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code demonstrates the main execution loop of an application designed for hot-reloading. It initializes a state and then repeatedly calls a function (`step`) provided by the hot-reloaded module. A delay is introduced in each iteration to allow for modifications to the underlying library code to be detected and reloaded. This pattern is essential for observing live changes without restarting the application. ```rust fn main() { let mut state = hot_lib::State { counter: 0 }; // Running in a loop so you can modify the code and see the effects loop { hot_lib::step(&mut state); std::thread::sleep(std::time::Duration::from_secs(1)); } } ``` -------------------------------- ### Configure Rust Library for Dynamic Loading Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This TOML snippet configures a Rust library's `Cargo.toml` to be built as a dynamic library (`dylib`) in addition to the default static library (`rlib`). This is a prerequisite for hot reloading. ```toml [package] name = "lib" version = "0.1.0" edition = "2024" [lib] crate-type = ["rlib", "dylib"] ``` -------------------------------- ### Subscribe to Library Reload Events in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code snippet shows how to use the `hot_lib_reloader` crate to subscribe to dynamic library reload events. The `#[hot_module(dylib = "lib")]` macro prepares the module for hot reloading, and `#[lib_change_subscription]` exposes a `LibReloadObserver` that can be used to wait for reload notifications. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { /* code from above */ // expose a type to subscribe to lib load events #[lib_change_subscription] pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {} } ``` -------------------------------- ### Main Function Waiting for Library Reloads in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code demonstrates a main function that initializes state, subscribes to library reload events using `hot_lib::subscribe()`, and enters a loop. Inside the loop, it calls the reloadable `hot_lib::step` function and then blocks using `lib_observer.wait_for_reload()` until the library has been reloaded, ensuring that subsequent calls use the updated code. ```rust fn main() { let mut state = hot_lib::State { counter: 0 }; let lib_observer = hot_lib::subscribe(); loop { hot_lib::step(&mut state); // blocks until lib was reloaded lib_observer.wait_for_reload(); } } ``` -------------------------------- ### Toggle Hot-Reload with Cargo Features (TOML) Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This TOML configuration demonstrates how to use Cargo features to conditionally enable hot-reloading. The 'reload' feature depends on the 'hot-lib-reloader' crate and a local 'lib' crate with a 'reload' feature. This allows switching between static and hot-reloadable builds. ```toml # Cargo.toml [features] default = [] reload = ["lib/reload", "dep:hot-lib-reloader"] [dependencies] lib = { path = "lib" } hot-lib-reloader = { version = "0.8", optional = true } ``` -------------------------------- ### Run Hot Reloading on Windows with Bevy Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/examples/bevy/README.md Execute Bevy with hot-reloading enabled on Windows. Similar to Linux/macOS, it uses `cargo watch` for compilation. However, it directs the executable to a separate `target-bin` directory to circumvent Windows file locking issues with dynamic libraries. ```shell cargo watch -w systems -w components -x "build -p systems --features dynamic" ``` ```shell cargo run --features reload --target-dir "target-bin" ``` -------------------------------- ### Specify Dylib Location with lib_dir Attribute Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md The `lib_dir` attribute in the `#[hot_module(...)]` macro allows you to specify a custom directory from which the dynamic library should be loaded. This overrides the default behavior of looking in standard debug or release build output folders. It's useful when your dylib is placed in a non-standard location. ```rust #[hot_lib_reloader::hot_module( dylib = "lib", lib_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/target/debug") )] mod hot_lib { /* ... */ } ``` -------------------------------- ### Run Hot Reloading on Linux/macOS with Bevy Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/examples/bevy/README.md Execute Bevy with hot-reloading enabled on Linux and macOS. This involves using `cargo watch` to monitor changes in 'systems' and 'components' directories, compiling with the 'dynamic' feature, and running the main application with the 'reload' feature. ```shell cargo watch -w systems -w components -x "build -p systems --features dynamic" ``` ```shell cargo run --features reload ``` -------------------------------- ### Customize Dylib Filename with loaded_lib_name_template Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md The `loaded_lib_name_template` parameter in the `hot_module` macro enables customization of the shadow filename for the dynamic library. This is beneficial for preventing conflicts when multiple processes hot reload the same library. It supports placeholders like `{lib_name}`, `{load_counter}`, `{pid}`, and `{uuid}` (requires the `uuid` feature flag). The default pattern is `{lib_name}-hot-{load_counter}`. ```rust #[hot_lib_reloader::hot_module( dylib = "lib", loaded_lib_name_template = "{lib_name}_hot_{pid}_{load_counter}_{uuid}" )] mod hot_lib { /* ... */ } ``` -------------------------------- ### Track Library Reload Count and Detect Updates (Rust) Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This snippet demonstrates how to track library reload counts and detect updates using generated helper functions provided by the hot-lib-reloader crate. It defines macros for versioning, update checking, and subscription to reload events, managing a loop that processes library updates. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::State; hot_functions_from_file!("lib/src/lib.rs"); #[lib_version] pub fn version() -> usize {} #[lib_updated] pub fn was_updated() -> bool {} #[lib_change_subscription] pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {} } fn main() { let mut state = hot_lib::State { counter: 0 }; loop { hot_lib::do_stuff(&mut state); let update_blocker = hot_lib::subscribe().wait_for_about_to_reload(); println!("about to reload..."); std::thread::sleep(std::time::Duration::from_secs(1)); drop(update_blocker); println!("ready for reload..."); hot_lib::subscribe().wait_for_reload(); println!("reloaded at version {} now", hot_lib::version()); // was_updated() returns true once after reload, then false assert!(hot_lib::was_updated()); assert!(!hot_lib::was_updated()); } } ``` -------------------------------- ### Implement Hot Module with serde_json::Value State in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code defines a hot module and a main function that utilizes `serde_json::Value` for flexible state management. The `hot_lib::State` struct contains an `inner` field of type `serde_json::Value`, allowing its structure and type to be modified without recompilation. The `hot_lib::step` function handles the serialization and deserialization of this state. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::State; hot_functions_from_file!("lib/src/lib.rs"); } fn main() { let mut state = hot_lib::State { inner: serde_json::json!(null), }; loop { state = hot_lib::step(state); std::thread::sleep(std::time::Duration::from_secs(1)); } } ``` -------------------------------- ### Conditionally Use Hot-Reloadable or Static Modules in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code demonstrates how to conditionally import modules based on the 'reload' feature flag. It uses `#[cfg(feature = "reload")]` to import from the hot-reloaded library and `#[cfg(not(feature = "reload"))]` to import from the static library. The `#[hot_lib_reloader::hot_module]` attribute is used to designate the hot-reloadable module. ```rust #[cfg(feature = "reload")] use hot_lib::*; #[cfg(not(feature = "reload"))] use lib::*; #[cfg(feature = "reload")] #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { /*...*/ } ``` -------------------------------- ### Define Serializable State and Step Function for Hot Reloading Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code defines the `State` struct and the `step` function used in conjunction with hot reloading. The `State` struct holds a `serde_json::Value`, enabling dynamic type changes. The `step` function, marked with `#[unsafe(no_mangle)]`, deserializes the `inner` value into `InnerState`, allows modifications, and then serializes it back into `serde_json::Value`. ```rust use serde::{Deserialize, Serialize}; #[derive(Debug)] pub struct State { pub inner: serde_json::Value, } #[derive(Deserialize, Serialize)] struct InnerState {} #[unsafe(no_mangle)] pub fn step(state: State) -> State { let inner: InnerState = serde_json::from_value(state.inner).unwrap_or(InnerState {}); // You can modify the InnerState layout freely and state.inner value here freely! State { inner: serde_json::to_value(inner).unwrap(), } } ``` -------------------------------- ### Conditionally Use Hot-Reload or Static Linking (Rust) Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This Rust code snippet shows how to conditionally use hot-reloaded code or statically linked code based on the 'reload' Cargo feature. It imports the necessary modules (`hot_lib` or `lib`) and uses the `#[cfg]` attribute to control which code paths are compiled. This is useful for managing build configurations for development and production. ```rust // Conditionally use hot-reload or static linking #[cfg(feature = "reload")] use hot_lib::*; #[cfg(not(feature = "reload"))] use lib::*; #[cfg(feature = "reload")] #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { pub use lib::*; hot_functions_from_file!("lib/src/lib.rs"); } fn main() { let mut state = State { counter: 0 }; loop { step(&mut state); std::thread::sleep(std::time::Duration::from_secs(1)); } } ``` -------------------------------- ### Hot Module Macro for Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md The `hot_module` attribute macro from `hot-lib-reloader` is used to define a module that wraps functions from a dynamic library. It enables hot-reloading capabilities by creating wrapper functions with identical signatures to those exported by the specified library. This macro requires the `dylib` argument to point to the crate name of the sub-crate containing the hot-reloadable functions. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { // Reads public no_mangle functions from lib.rs and generates hot-reloadable // wrapper functions with the same signature inside this module. // Note that this path relative to the project root (or absolute) hot_functions_from_file!("lib/src/lib.rs"); // Because we generate functions with the exact same signatures, // we need to import types used pub use lib::State; } ``` -------------------------------- ### Configure File Watch Debounce Duration for hot_module Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md The `file_watch_debounce` attribute within the `hot_module` macro allows you to set a custom debounce duration in milliseconds for file changes. This helps manage recompilation frequency, especially for large libraries. The default is 500ms, but can be decreased for faster reloads on smaller projects or increased if multiple updates are triggered per recompile. ```rust #[hot_module(dylib = "lib", file_watch_debounce = 50)] /* ... */ ``` -------------------------------- ### Conditional `no_mangle` for Hot-Reloadable Function (Rust) Source: https://context7.com/rksm/hot-lib-reloader-rs/llms.txt This Rust code defines a shared `State` struct and a `step` function in the `lib/src/lib.rs` file. The `#[cfg_attr(feature = "reload", unsafe(no_mangle))]` attribute ensures that the `step` function is exported with C linkage when the 'reload' feature is enabled, making it accessible for hot-reloading. Otherwise, it's a standard Rust function. ```rust // lib/src/lib.rs - conditional no_mangle pub struct State { pub counter: usize, } #[cfg_attr(feature = "reload", unsafe(no_mangle))] pub fn step(state: &mut State) { state.counter += 1; println!("iteration {}", state.counter); } ``` -------------------------------- ### Define Hot-Reloadable Function in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code defines a stateful structure and a public function `step` intended for hot reloading. The `#[unsafe(no_mangle)]` attribute ensures the function has a stable, predictable symbol name, allowing the dynamic library to be loaded and called by the executable without name mangling. Other functions without `no_mangle` can coexist. ```rust pub struct State { pub counter: usize, } #[unsafe(no_mangle)] pub fn step(state: &mut State) { state.counter += 1; println!("doing stuff in iteration {}", state.counter); } ``` -------------------------------- ### Conditionally Apply #[no_mangle] with Feature Flags in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code snippet shows how to conditionally apply the `#[no_mangle]` attribute based on a feature flag. The `#[cfg_attr(feature = "reload", unsafe(no_mangle))]` attribute ensures that `no_mangle` is only active when the 'reload' feature is enabled. This prevents unnecessary name mangling penalties in release builds when hot reloading is not in use. ```rust #[cfg_attr(feature = "reload", unsafe(no_mangle))] ``` -------------------------------- ### Check for Library Updates in Rust Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/README.md This Rust code defines a function `was_updated` within a hot-reloaded module. When called, it returns `true` immediately after a library reload has occurred and `false` otherwise, until the next reload. This provides a simple mechanism to detect if the library has changed. ```rust #[hot_lib_reloader::hot_module(dylib = "lib")] mod hot_lib { /* ... */ #[lib_updated] pub fn was_updated() -> bool {} } ``` -------------------------------- ### Apply `#[no_mangle]` conditionally in Debug Builds (Rust) Source: https://github.com/rksm/hot-lib-reloader-rs/blob/master/macro-no-mangle-if-debug/README.md The `#[no_mangle_if_debug]` attribute automatically adds `#[cfg(debug_assertions)]` and `#[no_mangle]` to a function when compiled in debug mode. In release mode, it does nothing, ensuring no performance penalty. This is primarily used to facilitate hot-reloading of libraries by exposing specific functions only when needed for debugging. ```rust #[no_mangle_if_debug] fn func() {} ``` ```rust #[cfg(debug_assertions)] #[unsafe(no_mangle)] fn func() {} #[cfg(not(debug_assertions))] fn func() {} ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.