### Example Usage of a Scraped Function Source: https://docs.rs/reloadify/latest/scrape-examples-help.html An example in `examples/ex.rs` demonstrating how to call a documented function from another crate. This code snippet will be included in the documentation for `a_func`. ```rust // examples/ex.rs fn main() { a_crate::a_func(); } ``` -------------------------------- ### Add and Get INI Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Demonstrates adding an INI configuration with a specific ID and then retrieving it. Verifies that the configuration is accessible by its ID. ```rust let r = Reloadify::new(); let id = ConfigId::new("pytest"); let _rx = r .add::(ReloadableConfig { id: id.clone(), path: fixture("pytest.ini"), format: Format::Ini, poll_interval: Duration::from_secs(10), debounce_delay: None, }) .expect("add should succeed"); let retrieved = r.get::(id).expect("get should succeed"); assert!(retrieved.contains_key("pytest")); ``` -------------------------------- ### Add and Get TOML Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Demonstrates adding a TOML configuration with a specific ID and then retrieving it. Ensures the configuration is correctly stored and accessible. ```rust let r = Reloadify::new(); let id = ConfigId::new("netlify"); let _rx = r .add::(ReloadableConfig { id: id.clone(), path: fixture("netlify.toml"), format: Format::Toml, poll_interval: Duration::from_secs(10), debounce_delay: None, }) .expect("add should succeed"); let retrieved = r.get::(id).expect("get should succeed"); assert!(retrieved.get("build").is_some()); ``` -------------------------------- ### Add and Get XML Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Demonstrates adding an XML configuration with a specific ID and preparing to retrieve it. This snippet is part of a larger roundtrip test for XML configurations. ```rust let r = Reloadify::new(); let id = ConfigId::new("tomcat"); let _rx = r .add::(ReloadableConfig { id: id.clone(), path: fixture("tomcat-users.xml"), ``` -------------------------------- ### Get Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Retrieves a configuration by its ID. The configuration must be deserializable into the specified type `C`. ```APIDOC ## get ### Description Retrieves a configuration from the `Reloadify` instance using its unique identifier. ### Arguments * `config_id` - The identifier of the configuration to retrieve. ### Returns Returns a `Result` containing the deserialized configuration of type `C` if found, otherwise returns a `ReloadifyError`. ### Type Parameters * `C`: The type to which the configuration should be deserialized. Must implement `DeserializeOwned`, `Send`, `Sync`, `Clone`, and `'static`. ``` -------------------------------- ### Get Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Retrieves a configuration by its ID. Ensures the configuration exists and can be downcasted to the expected type. ```rust pub fn get(&self, config_id: impl Into) -> Result where C: DeserializeOwned + Send + Sync + Clone + 'static, { let config_id = config_id.into(); match self.0.read() { Err(_) => Err(ReloadifyError::GetLockError), Ok(guard) => Ok(guard .get(&config_id) .ok_or(ReloadifyError::ConfigNotExist)? .value .downcast_ref::() .cloned() .ok_or(ReloadifyError::DowncastError)?), } } ``` -------------------------------- ### Test Get with String Literal Key Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Demonstrates that `Reloadify::get` can accept a string literal directly, without needing to explicitly create a `ConfigId`. ```rust let r = Reloadify::new(); // &str passed directly — no ConfigId::new needed let result = r.get::("literal-key"); assert!(matches!(result, Err(ReloadifyError::ConfigNotExist))); ``` -------------------------------- ### Basic Function Definition for Scraping Source: https://docs.rs/reloadify/latest/scrape-examples-help.html A simple public function in `src/lib.rs` that can be used as a target for scraped examples. ```rust // src/lib.rs pub fn a_func() {} ``` -------------------------------- ### Error::description Implementation (Deprecated) Source: https://docs.rs/reloadify/latest/reloadify/enum.ReloadifyError.html Deprecated method for getting a string description of the error. Use the `Display` implementation or `to_string()` instead. ```rust fn description(&self) -> &str ``` -------------------------------- ### Any Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method to get the TypeId of a type. ```APIDOC ## fn type_id(&self) -> TypeId ### Description Gets the `TypeId` of `self`. ### Method type_id ### Parameters - `self`: A reference to the instance. ### Returns - `TypeId`: The unique identifier for the type of `self`. ``` -------------------------------- ### Error::cause Implementation (Deprecated) Source: https://docs.rs/reloadify/latest/reloadify/enum.ReloadifyError.html Deprecated method for getting the underlying cause of the error. Use `Error::source` instead. ```rust fn cause(&self) -> Option<&dyn Error> ``` -------------------------------- ### Reloadify::add Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Adds a reloadable configuration to the Reloadify instance. This method allows you to specify a configuration file, its format, and polling intervals for automatic reloading. It returns a Receiver that can be used to get the latest deserialized configuration. ```APIDOC ## Reloadify::add ### Description Adds a reloadable configuration to the `Reloadify` instance. This method takes a `ReloadableConfig` which specifies the file path, format, and polling details for a configuration file that can be automatically reloaded. ### Method `add` ### Signature `pub fn add( &self, reloadable_config: ReloadableConfig, ) -> Result, ReloadifyError>` ### Type Parameters * `C`: The type of the configuration, which must implement `DeserializeOwned`, `Send`, `Sync`, `Clone`, and `'static`. ### Arguments * `reloadable_config` (ReloadableConfig) - Required - The reloadable configuration to add, including its ID, path, format, poll interval, and debounce delay. ### Returns * `Result, ReloadifyError>` - Returns a `Receiver` that yields the latest deserialized configuration of type `C` when it changes, or a `ReloadifyError` if an error occurs during the addition process. ### Examples ```rust // Example of adding a JSON configuration let rx = reloadify.add::(ReloadableConfig { id: TS_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/tsconfig.spec.json")?, format: Format::Json, poll_interval: Duration::from_secs(1), debounce_delay: None, })?; // Example of adding multiple configurations with different formats reloadify.add::(ReloadableConfig { id: COMPOSE_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/docker-compose.yaml")?, format: Format::Yaml, debounce_delay: None, poll_interval: Duration::from_secs(1), })?; reloadify.add::(ReloadableConfig { id: PYTEST_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/pytest.ini")?, format: Format::Ini, debounce_delay: None, poll_interval: Duration::from_millis(100), })?; ``` ``` -------------------------------- ### Load Configuration from File Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Loads and deserializes configuration from a given file path and format. Supports multiple serialization formats via feature flags. ```rust fn load(&self, path: &Path, format: &Format) -> Result { #[cfg(any( feature = "json", feature = "yaml", feature = "toml", feature = "xml", feature = "ini" ))] { let content = fs::read_to_string(path).map_err(ReloadifyError::LoadConfigError)?; match format { #[cfg(feature = "json")] Format::Json => serde_json::from_str::(&content) .map_err(|err| ReloadifyError::DeserializeError(err.to_string())), #[cfg(feature = "yaml")] Format::Yaml => serde_yaml_ng::from_str::(&content) .map_err(|err| ReloadifyError::DeserializeError(err.to_string())), #[cfg(feature = "toml")] Format::Toml => serde_toml::from_str::(&content) .map_err(|err| ReloadifyError::DeserializeError(err.to_string())), #[cfg(feature = "xml")] Format::Xml => serde_xml::from_str::(&content) .map_err(|err| ReloadifyError::DeserializeError(err.to_string())), #[cfg(feature = "ini")] Format::Ini => serde_ini::from_str::(&content) .map_err(|err| ReloadifyError::DeserializeError(err.to_string())), } } #[cfg(not(any( feature = "json", feature = "yaml", feature = "toml", ``` -------------------------------- ### Load Initial Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Loads the initial configuration from a file path and format. This is used when setting up a new reloadable configuration. ```rust let initial_cfg = \ self.load::(reloadable_config.path.as_path(), &reloadable_config.format)?;\ tx.send(initial_cfg.clone()).map_err(|_| ReloadifyError::SendError)?;\ \ let mut guard = self.0.write().map_err(|_| ReloadifyError::GetLockError)?;\ guard\ .entry(reloadable_config.id) .or_insert(Config { value: Box::new(initial_cfg), _watcher: watcher }); ``` -------------------------------- ### Build Absolute Path to Config Fixture Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Helper function to construct the absolute path to configuration files located in the examples/config directory. Useful for setting up tests. ```rust fn fixture(filename: &str) -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples").join("config").join(filename) } ``` -------------------------------- ### Load and Verify TOML Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests loading a netlify.toml file and asserts the presence of the 'build' section. Ensures correct parsing of TOML structure. ```rust #[test] fn load_toml_file() { let r = Reloadify::new(); let cfg: toml::Value = r.load(&fixture("netlify.toml"), &Format::Toml).expect("should load TOML config"); let build = cfg.get("build").expect("should have [build] section"); } ``` -------------------------------- ### Add multiple configurations with different formats Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Adds multiple configurations, each with a potentially different format (e.g., YAML, INI). This is useful for managing diverse configuration files within a single application. ```rust 7fn main() -> Result<(), Box> { 8 let reloadify = Reloadify::new(); 9 10 reloadify.add::(ReloadableConfig { 11 id: COMPOSE_CONFIG_ID.into(), 12 path: PathBuf::from_str("examples/config/docker-compose.yaml")?, 13 format: Format::Yaml, 14 debounce_delay: None, 15 poll_interval: Duration::from_secs(1), 16 })?; 17 reloadify.add::(ReloadableConfig { 18 id: PYTEST_CONFIG_ID.into(), 19 path: PathBuf::from_str("examples/config/pytest.ini")?, 20 format: Format::Ini, 21 debounce_delay: None, 22 poll_interval: Duration::from_millis(100), 23 })?; 24 25 let compose_config = reloadify.get::(COMPOSE_CONFIG_ID)?; 26 let pytest_config = reloadify.get::(PYTEST_CONFIG_ID)?; 27 28 // Do something with compose_config and pytest_config... 29 println!("compose_config={{:?}}\npytest_config={{:?}}", compose_config, pytest_config); 30 31 Ok(()) 32} ``` -------------------------------- ### Add and Retrieve YAML Configuration (Roundtrip) Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests adding a reloadable YAML configuration and then retrieving it. Verifies that the retrieved configuration contains the expected structure. ```rust #[test] fn add_and_get_roundtrip() { let r = Reloadify::new(); let id = ConfigId::new("compose"); let _rx = r .add::(ReloadableConfig { id: id.clone(), path: fixture("docker-compose.yaml"), format: Format::Yaml, poll_interval: Duration::from_secs(10), debounce_delay: None, }) .expect("add should succeed"); let retrieved = r.get::(id).expect("get should succeed"); assert!(retrieved.get("services").is_some()); } ``` -------------------------------- ### Load and Verify YAML Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests loading a docker-compose.yaml file and asserts the presence of specific keys. Ensures correct parsing of YAML structure. ```rust #[test] fn load_yaml_file() { let r = Reloadify::new(); let cfg: serde_yaml_ng::Value = r .load(&fixture("docker-compose.yaml"), &Format::Yaml) .expect("should load YAML config"); let services = cfg.get("services").expect("should have services key"); assert!(services.get("minecraft").is_some()); } ``` -------------------------------- ### Default Reloadify Instance Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Demonstrates creating a default instance of Reloadify. This instance is ready for configuration loading but will return an error if a non-existent config is requested. ```rust impl Default for Reloadify { fn default() -> Self { Self::new() } } ``` -------------------------------- ### Reloadify::new Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Creates a new instance of the `Reloadify` struct, initializing an empty collection for reloadable configurations. ```APIDOC ## Reloadify::new ### Description Creates a new `Reloadify` instance with an empty configuration map. ### Method ```rust pub fn new() -> Self ``` ### Returns A new `Reloadify` instance. ``` -------------------------------- ### Error::provide Implementation (Nightly-only) Source: https://docs.rs/reloadify/latest/reloadify/enum.ReloadifyError.html An experimental, nightly-only API for providing type-based access to error context, intended for error reporting tools. ```rust fn provide<'a>(&'a self, request: &mut Request<'a>) ``` -------------------------------- ### Add and Retrieve JSON Configuration (Roundtrip) Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests adding a reloadable JSON configuration and then retrieving it. Verifies that the retrieved configuration matches the added one and that the initial value is sent through the channel. ```rust #[test] fn add_and_get_roundtrip() { let r = Reloadify::new(); let id = ConfigId::new("tsconfig"); let rx = r .add::(ReloadableConfig { id: id.clone(), path: fixture("tsconfig.spec.json"), format: Format::Json, poll_interval: Duration::from_secs(10), debounce_delay: None, }) .expect("add should succeed"); let retrieved = r.get::(id).expect("get should succeed"); assert_eq!(retrieved.extends, "./tsconfig.json"); // channel must carry the initial value let from_rx = rx.try_recv().expect("initial value on channel"); assert_eq!(from_rx.extends, "./tsconfig.json"); } ``` -------------------------------- ### Add Multiple Configurations with Different Formats Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Adds multiple reloadable configurations, each with a potentially different format (e.g., YAML, INI). This is useful when managing various configuration files within the same application. ```rust fn main() -> Result<(), Box> { let reloadify = Reloadify::new(); reloadify.add::(ReloadableConfig { id: COMPOSE_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/docker-compose.yaml")?, format: Format::Yaml, debounce_delay: None, poll_interval: Duration::from_secs(1), })?; reloadify.add::(ReloadableConfig { id: PYTEST_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/pytest.ini")?, format: Format::Ini, debounce_delay: None, poll_interval: Duration::from_millis(100), })?; let compose_config = reloadify.get::(COMPOSE_CONFIG_ID)?; let pytest_config = reloadify.get::(PYTEST_CONFIG_ID)?; // Do something with compose_config and pytest_config... println!("compose_config={compose_config:?}\npytest_config={pytest_config:?}"); Ok(()) } ``` -------------------------------- ### Clone To Uninit (Nightly Experimental) Source: https://docs.rs/reloadify/latest/reloadify/struct.ReloadableConfig.html An experimental nightly-only API for performing copy-assignment from a source to an uninitialized destination. ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### Load XML Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Loads an XML configuration file representing Tomcat users and roles. Asserts the number of users and roles, and specific details of the first user. ```rust let r = Reloadify::new(); let cfg: TomcatUsers = r.load(&fixture("tomcat-users.xml"), &Format::Xml).expect("should load XML config"); assert_eq!(cfg.user.len(), 2); assert_eq!(cfg.user[0].username, "system"); assert_eq!(cfg.user[0].password, "manager"); assert_eq!(cfg.user[0].roles, "admin-gui,manager-gui"); assert_eq!(cfg.role.len(), 1); assert_eq!(cfg.role[0].rolename, "manager-script"); ``` -------------------------------- ### ConfigId::new Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Creates a new `ConfigId` with the given identifier string. ```APIDOC ## ConfigId::new ### Description Creates a new `ConfigId` from a string. ### Method ```rust pub fn new>(id: S) -> Self ``` ### Parameters #### Path Parameters * `id` (S: Into) - Required - The string identifier for the configuration. ### Returns A new `ConfigId` instance. ``` -------------------------------- ### Create a new Reloadify instance Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Instantiates a new Reloadify struct. This is the entry point for managing reloadable configurations. ```rust pub struct Reloadify(/* private fields */); ``` -------------------------------- ### Handle Missing YAML Configuration File Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests the behavior when attempting to load a non-existent YAML configuration file. Verifies that a LoadConfigError is returned. ```rust #[test] fn load_missing_file() { let r = Reloadify::new(); let result = r.load::( &PathBuf::from("/nonexistent/reloadify_test.yaml"), &Format::Yaml, ); assert!(matches!(result, Err(ReloadifyError::LoadConfigError(_)))); } ``` -------------------------------- ### Handle Missing JSON Configuration File Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests the behavior when attempting to load a non-existent JSON configuration file. Verifies that a LoadConfigError is returned. ```rust #[test] fn load_missing_file() { let r = Reloadify::new(); let result = r.load::( &PathBuf::from("/nonexistent/reloadify_test.json"), &Format::Json, ); assert!(matches!(result, Err(ReloadifyError::LoadConfigError(_)))); } ``` -------------------------------- ### CloneToUninit Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides an unsafe method for copying data to uninitialized memory. ```APIDOC ## unsafe fn clone_to_uninit(&self, dest: *mut u8) ### Description Performs copy-assignment from `self` to `dest`. ### Method clone_to_uninit ### Parameters - `self`: A reference to the source value. - `dest`: A raw pointer to the destination memory location. ``` -------------------------------- ### Load and Verify JSON Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests loading a tsconfig.spec.json file and asserts its properties. Ensures correct parsing of extends, compiler options, files, and include directives. ```rust #[test] fn load_json_file() { let r = Reloadify::new(); let cfg: TsConfig = r .load(&fixture("tsconfig.spec.json"), &Format::Json) .expect("should load JSON config"); assert_eq!(cfg.extends, "./tsconfig.json"); assert_eq!(cfg.compiler_options.out_dir, "./out-tsc/spec"); assert_eq!(cfg.compiler_options.types, vec!["jasmine"]); assert_eq!(cfg.files.len(), 2); assert_eq!(cfg.include.len(), 2); } ``` -------------------------------- ### Add Reloadable Configuration with File Watching Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Adds a reloadable configuration and sets up a file watcher. Handles initial load and debounces rapid file modifications. ```rust impl Reloadify { /// Creates a new `Reloadify` instance. pub fn new() -> Self { Self(Arc::new(RwLock::new(HashMap::new()))) } /// Adds a reloadable configuration to the `Reloadify` instance. /// /// # Arguments /// /// * `reloadable_config` - The reloadable configuration to add. /// /// # Returns /// /// Returns a result containing the deserialized configuration if successful, or an error if an /// error occurred. #[allow(unreachable_code, unused_variables)] pub fn add(&self, reloadable_config: ReloadableConfig) -> Result, ReloadifyError> where C: DeserializeOwned + Send + Sync + Clone + 'static, { let (tx, rx) = channel(); // Start the watcher *before* the initial load so no file-change // events are lost in the window between load and watch. let c = reloadable_config.clone(); let s = self.clone(); let debounce_delay = c.debounce_delay; let last_event = Arc::new(Mutex::new(Instant::now())); // Clone the sender so the closure can own its copy while we keep // one for the initial send after the load. let tx_initial = tx.clone(); let mut watcher = RecommendedWatcher::new( move |r: Result| { if let Ok(event) = r { if let EventKind::Modify(ModifyKind::Data(DataChange::Content)) = event.kind { if let Some(delay) = debounce_delay { if let Ok(mut last) = last_event.lock() { if last.elapsed() < delay { return; } *last = Instant::now(); } // if lock is poisoned, skip debounce and reload anyway } ``` -------------------------------- ### Convert string slice to ConfigId Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html This implementation allows creating a ConfigId directly from a string slice (`&str`). It's a convenient way to initialize a ConfigId when you have a string literal or a slice. ```rust fn from(s: &str) -> Self ``` -------------------------------- ### Convert String to ConfigId Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html This implementation allows creating a ConfigId directly from a `String`. It consumes the `String` and creates a `ConfigId` from it. ```rust fn from(s: String) -> Self ``` -------------------------------- ### Load Missing INI File Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests the scenario where an INI configuration file is missing. Expects the function to return a `LoadConfigError`. ```rust let r = Reloadify::new(); let result = r.load::(&PathBuf::from("/nonexistent/reloadify_test.ini"), &Format::Ini); assert!(matches!(result, Err(ReloadifyError::LoadConfigError(_)))); ``` -------------------------------- ### Compare ConfigId for Inequality Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html Implement the PartialEq trait to enable inequality comparisons between ConfigId instances using the `!=` operator. The default implementation is usually sufficient. ```rust fn ne(&self, other: &Rhs) -> bool ``` -------------------------------- ### Create a new ConfigId Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html Use this function to create a new ConfigId instance with a given string identifier. The identifier can be any type that can be converted into a String. ```rust pub fn new>(id: S) -> Self ``` -------------------------------- ### Test ConfigId From Owned String Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Verifies that `ConfigId` can be created from an owned `String`. ```rust let id = ConfigId::from(String::from("owned")); assert_eq!(id, ConfigId::new("owned")); ``` -------------------------------- ### Compare ConfigId for Equality Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html Implement the PartialEq trait to enable equality comparisons between ConfigId instances using the `==` operator. ```rust fn eq(&self, other: &ConfigId) -> bool ``` -------------------------------- ### Test Loading and Retrieving XML Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html This test verifies the ability to add and retrieve an XML configuration. It asserts the number of users and roles loaded from the configuration. ```rust let retrieved = r.get::(id).expect("get should succeed"); assert_eq!(retrieved.user.len(), 2); assert_eq!(retrieved.role.len(), 1); ``` -------------------------------- ### Add and listen for configuration changes Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Adds a reloadable configuration and returns a receiver to listen for its updates. Use this when you need to react to configuration changes in real-time. ```rust 23fn main() -> Result<(), Box> { 24 let reloadify = Reloadify::new(); 25 26 let rx = reloadify.add::(ReloadableConfig { 27 id: TS_CONFIG_ID.into(), 28 path: PathBuf::from_str("examples/config/tsconfig.spec.json")?, 29 format: Format::Json, 30 poll_interval: Duration::from_secs(1), 31 debounce_delay: None, 32 })?; 33 34 // Optional: Spawn a thread to listen for the latest configuration. 35 std::thread::spawn(move || { 36 for latest_cfg in rx { 37 // Do something with the latest configuration... 38 println!("Received latest config: {:?}", latest_cfg); 39 } 40 }); 41 42 let ts_config = reloadify.get::(TS_CONFIG_ID)?; 43 44 // Do something with ts_config... 45 println!("{:?}", ts_config); 46 47 Ok(()) 48} ``` -------------------------------- ### Add Multiple Formats to Reloadify Source: https://docs.rs/reloadify/latest/src/multi_format/multi_format.rs.html Adds YAML and INI configuration files to Reloadify for monitoring. Specify the configuration ID, path, format, and polling interval for each. ```rust use reloadify::{Format, ReloadableConfig, Reloadify}; use std::{path::PathBuf, str::FromStr, time::Duration}; const COMPOSE_CONFIG_ID: &str = "docker-compose"; const PYTEST_CONFIG_ID: &str = "pytest"; fn main() -> Result<(), Box> { let reloadify = Reloadify::new(); reloadify.add::(ReloadableConfig { id: COMPOSE_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/docker-compose.yaml")?, format: Format::Yaml, debounce_delay: None, poll_interval: Duration::from_secs(1), })?; reloadify.add::(ReloadableConfig { id: PYTEST_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/pytest.ini")?, format: Format::Ini, debounce_delay: None, poll_interval: Duration::from_millis(100), })?; let compose_config = reloadify.get::(COMPOSE_CONFIG_ID)?; let pytest_config = reloadify.get::(PYTEST_CONFIG_ID)?; // Do something with compose_config and pytest_config... println!("compose_config={compose_config:?}\npytest_config={pytest_config:?}"); Ok(()) } mod pytest { use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PyTestConfig { pub pytest: PyTest, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PyTest { addopts: String, junit_suite_name: String, junit_family: String, } } mod compose { use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug)] pub struct ComposeConfig { #[serde(rename = "services")] services: Services, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Services { #[serde(rename = "minecraft")] minecraft: Minecraft, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Minecraft { #[serde(rename = "image")] image: String, #[serde(rename = "ports")] ports: Vec, #[serde(rename = "environment")] environment: Environment, #[serde(rename = "deploy")] deploy: Deploy, #[serde(rename = "volumes")] volumes: Vec, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Deploy { #[serde(rename = "resources")] resources: Resources, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Resources { #[serde(rename = "limits")] limits: Limits, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Limits { #[serde(rename = "memory")] memory: String, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Environment { #[serde(rename = "EULA")] eula: String, } } ``` -------------------------------- ### Reloadify Configuration Structures Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Defines the Format, ConfigId, and ReloadableConfig structures used for managing reloadable configurations. ```rust use notify::{ event::{DataChange, ModifyKind}, Error, Event, EventKind, RecommendedWatcher, Watcher, }; use serde::de::DeserializeOwned; #[cfg(feature = "xml")] use serde_xml_rs as serde_xml; #[cfg(any( feature = "json", feature = "yaml", feature = "toml", feature = "xml", feature = "ini" ))] use std::fs; use std::{ any::Any, collections::HashMap, path::{Path, PathBuf}, sync::{ mpsc::{channel, Receiver}, Arc, Mutex, RwLock, }, time::{Duration, Instant}, }; #[cfg(feature = "toml")] use toml as serde_toml; /// Represents the format of the configuration file. #[derive(Clone, Debug)] pub enum Format { #[cfg(feature = "json")] Json, #[cfg(feature = "yaml")] Yaml, #[cfg(feature = "toml")] Toml, #[cfg(feature = "xml")] Xml, #[cfg(feature = "ini")] Ini, } /// Represents the identifier of a configuration. #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)] pub struct ConfigId(String); impl ConfigId { /// Creates a new `ConfigId` with the given identifier. pub fn new>(id: S) -> Self { Self(id.into()) } } impl From<&str> for ConfigId { fn from(s: &str) -> Self { Self(s.to_owned()) } } impl From for ConfigId { fn from(s: String) -> Self { Self(s) } } struct Config { value: Box, _watcher: RecommendedWatcher, } /// Represents a collection of reloadable configurations. #[derive(Clone)] pub struct Reloadify(Arc>>); /// Represents an error that can occur in the `Reloadify` struct. #[derive(Debug, thiserror::Error)] pub enum ReloadifyError { #[error("Failed to acquire lock")] GetLockError, #[error("Failed to load config: {0}")] LoadConfigError(#[from] std::io::Error), #[error("Failed to deserialize config: {0}")] DeserializeError(String), #[error("Failed to watch: {0}")] WatchError(#[from] notify::Error), #[error("Failed to downcast")] DowncastError, #[error("Config does not exist")] ConfigNotExist, #[error("Failed to send config")] SendError, } /// Represents a reloadable configuration. #[derive(Debug, Clone)] pub struct ReloadableConfig { pub id: ConfigId, pub path: PathBuf, pub format: Format, pub poll_interval: Duration, /// Optional debounce delay. Coalesces rapid writes (e.g. editor saves) /// into a single reload event. pub debounce_delay: Option, } ``` -------------------------------- ### Load INI Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Loads an INI configuration file and asserts specific key-value pairs within the parsed structure. Assumes the INI file has a `[pytest]` section. ```rust let r = Reloadify::new(); let cfg: IniMap = r.load(&fixture("pytest.ini"), &Format::Ini).expect("should load INI config"); let pytest = cfg.get("pytest").expect("should have [pytest] section"); assert_eq!(pytest.get("addopts").and_then(|v| v.as_deref()), Some("--tb=short -rxs")); assert_eq!( pytest.get("junit_suite_name").and_then(|v| v.as_deref()), Some("docker-py") ); ``` -------------------------------- ### Load Missing TOML File Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests the behavior when attempting to load a TOML configuration file that does not exist. Expects a `LoadConfigError`. ```rust let r = Reloadify::new(); let result = r.load::( &PathBuf::from("/nonexistent/reloadify_test.toml"), &Format::Toml, ); assert!(matches!(result, Err(ReloadifyError::LoadConfigError(_)))); ``` -------------------------------- ### Add and Receive Reloadable Configuration Source: https://docs.rs/reloadify/latest/src/basic/basic.rs.html This snippet shows how to add a configuration file (tsconfig.spec.json) to be monitored by Reloadify. It specifies the file path, format (JSON), polling interval, and optionally a debounce delay. It also demonstrates how to subscribe to configuration updates using a receiver. ```Rust use reloadify::{Format, ReloadableConfig, Reloadify}; use serde::{Deserialize, Serialize}; use std::{path::PathBuf, str::FromStr, time::Duration}; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct TsConfig { pub extends: String, #[serde(rename = "compilerOptions")] pub compiler_options: CompilerOptions, pub files: Vec, pub include: Vec, } #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct CompilerOptions { #[serde(rename = "outDir")] pub out_dir: String, pub types: Vec, } const TS_CONFIG_ID: &str = "tsconfig"; fn main() -> Result<(), Box> { let reloadify = Reloadify::new(); let rx = reloadify.add::(ReloadableConfig { id: TS_CONFIG_ID.into(), path: PathBuf::from_str("examples/config/tsconfig.spec.json")?, format: Format::Json, poll_interval: Duration::from_secs(1), debounce_delay: None, })?; // Optional: Spawn a thread to listen for the latest configuration. std::thread::spawn(move || { for latest_cfg in rx { // Do something with the latest configuration... println!("Received latest config: {:?}", latest_cfg); } }); let ts_config = reloadify.get::(TS_CONFIG_ID)?; // Do something with ts_config... println!("{:?}", ts_config); Ok(()) } ``` -------------------------------- ### From Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method to create a value from another type. ```APIDOC ## fn from(t: T) -> T ### Description Returns the argument unchanged. ### Method from ### Parameters - `t`: The value to convert from. ### Returns - `T`: The converted value. ``` -------------------------------- ### Default Implementation for Reloadify Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method to create a default instance of Reloadify. ```APIDOC ## fn default() -> Self ### Description Returns the “default value” for a type. ### Method default ### Returns - `Self`: A default instance of Reloadify. ``` -------------------------------- ### Test New Reloadify Instance Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Verifies that a newly created Reloadify instance correctly returns a `ConfigNotExist` error when attempting to retrieve a non-existent configuration. ```rust let r = Reloadify::new(); let result = r.get::("nonexistent"); assert!(matches!(result, Err(ReloadifyError::ConfigNotExist))); ``` -------------------------------- ### TryInto Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method for fallible conversion into another type. ```APIDOC ## fn try_into(self) -> Result>::Error> ### Description Performs the conversion. ### Method try_into ### Parameters - `self`: The value to convert. ### Returns - `Result>::Error>`: The converted value or an error if the conversion failed. ``` -------------------------------- ### Test Default Constructor Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Ensures that calling `Reloadify::default()` creates a valid instance that still returns an error for any configuration retrieval. ```rust let r = Reloadify::default(); assert!(r.get::("any").is_err()); ``` -------------------------------- ### Test Multiple Configurations in Reloadify Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html This test demonstrates adding and retrieving configurations in different formats (JSON and YAML) within a single Reloadify instance. It asserts that specific keys exist in the retrieved configurations. ```rust r.add::(ReloadableConfig { id: json_id.clone(), path: fixture("tsconfig.spec.json"), format: Format::Json, poll_interval: Duration::from_secs(10), debounce_delay: None, }) .expect("add json"); r.add::(ReloadableConfig { id: yaml_id.clone(), path: fixture("docker-compose.yaml"), format: Format::Yaml, poll_interval: Duration::from_secs(10), debounce_delay: None, }) .expect("add yaml"); let json_cfg = r.get::(json_id).expect("get json"); let yaml_cfg = r.get::(yaml_id).expect("get yaml"); assert!(json_cfg.get("extends").is_some()); assert!(yaml_cfg.get("services").is_some()); ``` -------------------------------- ### Test ConfigId Serde Roundtrip Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Validates that `ConfigId` can be correctly serialized to JSON and then deserialized back into a `ConfigId` instance, preserving its value. ```rust let id = ConfigId::new("my-config"); let json = serde_json::to_string(&id).unwrap(); let back: ConfigId = serde_json::from_str(&json).unwrap(); assert_eq!(id, back); ``` -------------------------------- ### TryFrom Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method for fallible conversion from another type. ```APIDOC ## fn try_from(value: U) -> Result>::Error> ### Description Performs the conversion. ### Method try_from ### Parameters - `value`: The value to convert from. ### Returns - `Result>::Error>`: The converted value or an error if the conversion failed. ``` -------------------------------- ### Borrow Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method for immutable borrowing. ```APIDOC ## fn borrow(&self) -> &T ### Description Immutably borrows from an owned value. ### Method borrow ### Parameters - `self`: A reference to the owned value. ### Returns - `&T`: An immutable reference to the borrowed value. ``` -------------------------------- ### Clone Implementation for Reloadify Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides methods for cloning Reloadify instances. ```APIDOC ## fn clone(&self) -> Reloadify ### Description Returns a duplicate of the value. ### Method clone ### Parameters - `self`: A reference to the Reloadify instance. ### Returns - `Reloadify`: A new instance that is a duplicate of the original. ``` ```APIDOC ## fn clone_from(&mut self, source: &Self) ### Description Performs copy-assignment from `source`. ### Method clone_from ### Parameters - `self`: A mutable reference to the Reloadify instance to be updated. - `source`: A reference to the source Reloadify instance to copy from. ``` -------------------------------- ### TryInto for T Implementation Source: https://docs.rs/reloadify/latest/reloadify/enum.ReloadifyError.html Generic implementation allowing types to be converted into other types using `try_into()`, provided a `TryFrom` implementation exists. ```rust fn try_into(self) -> Result>::Error> ``` -------------------------------- ### Into Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method to convert a value into another type. ```APIDOC ## fn into(self) -> U ### Description Calls `U::from(self)`. ### Method into ### Parameters - `self`: The value to convert. ### Returns - `U`: The converted value. ``` -------------------------------- ### ToString for T Implementation Source: https://docs.rs/reloadify/latest/reloadify/enum.ReloadifyError.html Generic implementation that allows any type implementing `Display` to be converted into a `String` using `to_string()`. ```rust fn to_string(&self) -> String ``` -------------------------------- ### TryFrom Implementation Source: https://docs.rs/reloadify/latest/reloadify/struct.ReloadableConfig.html Attempts to convert a value of type U into a value of type T, returning a Result. ```rust type Error = Infallible ``` ```rust fn try_from(value: U) -> Result>::Error> ``` -------------------------------- ### Clone Implementation for ReloadableConfig Source: https://docs.rs/reloadify/latest/reloadify/struct.ReloadableConfig.html Provides a method to create a duplicate of a ReloadableConfig instance. ```rust fn clone(&self) -> ReloadableConfig ``` -------------------------------- ### BorrowMut Implementation for T Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Provides a method for mutable borrowing. ```APIDOC ## fn borrow_mut(&mut self) -> &mut T ### Description Mutably borrows from an owned value. ### Method borrow_mut ### Parameters - `self`: A mutable reference to the owned value. ### Returns - `&mut T`: A mutable reference to the borrowed value. ``` -------------------------------- ### Format Enum Definition Source: https://docs.rs/reloadify/latest/reloadify/enum.Format.html Defines the possible formats for configuration files supported by Reloadify. Use this enum to specify or parse configuration files. ```rust pub enum Format { Json, Yaml, Toml, Xml, Ini, } ``` -------------------------------- ### TryFrom for T Implementation Source: https://docs.rs/reloadify/latest/reloadify/enum.ReloadifyError.html Generic implementation for attempting to convert one type into another, returning a `Result`. ```rust fn try_from(value: U) -> Result>::Error> ``` -------------------------------- ### Handle Malformed JSON Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Tests loading a file with invalid JSON content. Asserts that a DeserializeError is returned upon parsing failure. ```rust #[test] fn load_malformed_json() { let tmp = std::env::temp_dir().join("reloadify_test_malformed.json"); std::fs::write(&tmp, "{ not valid json }").unwrap(); let r = Reloadify::new(); let result = r.load::(&tmp, &Format::Json); let _ = std::fs::remove_file(&tmp); assert!( matches!(result, Err(ReloadifyError::DeserializeError(_))), "expected DeserializeError, got {result:?}" ); } ``` -------------------------------- ### Into Implementation Source: https://docs.rs/reloadify/latest/reloadify/struct.ReloadableConfig.html Converts a value of type T into a value of type U, provided that U implements From. ```rust fn into(self) -> U ``` -------------------------------- ### Serialize ConfigId Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html Implement this trait to allow serialization of the ConfigId struct into various formats using Serde. This is useful for saving or transmitting configuration data. ```rust fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error> where __S: Serializer, ``` -------------------------------- ### Test Handling Missing Configuration File Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html This test checks the behavior when attempting to load a configuration from a non-existent file. It asserts that a `ReloadifyError::LoadConfigError` is returned. ```rust let result = r.load::( &PathBuf::from("/nonexistent/reloadify_test.xml"), &Format::Xml, ); assert!(matches!(result, Err(ReloadifyError::LoadConfigError(_)))); ``` -------------------------------- ### Test ConfigId Equality Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Validates the equality and inequality comparisons for `ConfigId` instances, ensuring that IDs with the same string value are equal and different ones are not. ```rust let a = ConfigId::new("foo"); let b = ConfigId::new("foo"); let c = ConfigId::new("bar"); assert_eq!(a, b); assert_ne!(a, c); ``` -------------------------------- ### Test ConfigId From String Literal Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Checks if `ConfigId` can be correctly created from a string literal using the `Into` trait. ```rust let id: ConfigId = "mycfg".into(); assert_eq!(id, ConfigId::new("mycfg")); ``` -------------------------------- ### TryInto Implementation Source: https://docs.rs/reloadify/latest/reloadify/struct.ReloadableConfig.html Attempts to convert a value of type T into a value of type U, returning a Result. ```rust type Error = >::Error ``` ```rust fn try_into(self) -> Result>::Error> ``` -------------------------------- ### Test Remove Nonexistent Configuration Source: https://docs.rs/reloadify/latest/src/reloadify/lib.rs.html Ensures that attempting to remove a configuration that does not exist in Reloadify results in a `ConfigNotExist` error. ```rust let r = Reloadify::new(); let result = r.remove("nonexistent"); assert!(matches!(result, Err(ReloadifyError::ConfigNotExist))); ``` -------------------------------- ### Reloadify::get Source: https://docs.rs/reloadify/latest/reloadify/struct.Reloadify.html Retrieves a configuration from the Reloadify instance. This method allows you to fetch a specific configuration by its ID, deserializing it into the specified type `C`. ```APIDOC ## Reloadify::get ### Description Retrieves a configuration from the `Reloadify` instance. ### Method `get` ### Signature `pub fn get( &self, config_id: impl Into, ) -> Result` ### Type Parameters * `C`: The type to deserialize the configuration into. Must implement `DeserializeOwned`, `Send`, `Sync`, `Clone`, and `'static`. ### Arguments * `config_id` - The identifier of the configuration to retrieve. ### Returns Returns a `Result` containing the deserialized configuration of type `C` if successful, or a `ReloadifyError` if the configuration does not exist or an error occurred during retrieval or deserialization. ``` -------------------------------- ### Hash Slice of ConfigId Source: https://docs.rs/reloadify/latest/reloadify/struct.ConfigId.html Implement this function to efficiently hash a slice of ConfigId values. This can be useful for optimizing hashing operations on collections of ConfigIds. ```rust fn hash_slice(data: &[Self], state: &mut H) where H: Hasher, Self: Sized, ``` -------------------------------- ### Clone From Implementation for ReloadableConfig Source: https://docs.rs/reloadify/latest/reloadify/struct.ReloadableConfig.html Enables copy-assignment from one ReloadableConfig instance to another. ```rust fn clone_from(&mut self, source: &Self) ```