### Rust: Real-World Example with Waitup Configuration and Targets Source: https://docs.rs/waitup/latest/waitup/types/index Provides a comprehensive Rust example showcasing the readability and type safety achieved with waitup's `WaitConfig`, `Target`, `Hostname`, and `Port` NewTypes for configuring and connecting to services. ```rust use waitup::{Port, Hostname, StatusCode, RetryCount, WaitConfig, Target}; use std::time::Duration; // Clear, self-documenting configuration let config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .max_retries(Some(RetryCount::MODERATE.get())) .build(); // Type-safe target construction let database = Target::tcp( Hostname::localhost().as_str(), Port::postgres().get() ).unwrap(); println!("Connecting to {} on port {}", "localhost", if database.port().map(|p| Port::new(p).unwrap().is_system_port()).unwrap_or(false) { "system port" } else { "user port" } ); ``` -------------------------------- ### Real-World Example: waitup Configuration and Target Source: https://docs.rs/waitup/1.1.0/waitup/types/index Presents a comprehensive example of using waitup's NewTypes for configuration and service targeting. It demonstrates building a `WaitConfig` and constructing a `Target` with type-safe hostnames and ports, showcasing the readability and safety benefits. ```rust use waitup::{Port, Hostname, StatusCode, RetryCount, WaitConfig, Target}; use std::time::Duration; // Clear, self-documenting configuration let config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .max_retries(Some(RetryCount::MODERATE.get())) .build(); // Type-safe target construction let database = Target::tcp( Hostname::localhost().as_str(), Port::postgres().get() ).unwrap(); println!("Connecting to {} on port \{}", "localhost", if database.port().map(|p| Port::new(p).unwrap().is_system_port()).unwrap_or(false) { "system port" } else { "user port" } ); ``` -------------------------------- ### Microservice Readiness WaitConfig Examples in Rust Source: https://docs.rs/waitup/1.1.0/waitup/config/index Provides two distinct `WaitConfig` examples tailored for microservice readiness checks. One configures fast polling for local services, while the other uses conservative settings for external services, demonstrating adaptive configuration. ```rust use waitup::WaitConfig; use std::time::Duration; // Fast polling for local services let local_config = WaitConfig::builder() .timeout(Duration::from_secs(10)) .interval(Duration::from_millis(100)) .max_interval(Duration::from_secs(1)) .connection_timeout(Duration::from_secs(2)) .build(); // Conservative settings for external services let external_config = WaitConfig::builder() .timeout(Duration::from_secs(120)) .interval(Duration::from_secs(2)) .max_interval(Duration::from_secs(30)) .connection_timeout(Duration::from_secs(15)) .max_retries(Some(10)) .build(); ``` -------------------------------- ### Rust Waitup Library Real-World Example Source: https://docs.rs/waitup/1.1.0/src/waitup/types A practical example showcasing the waitup library's `WaitConfig`, `Target`, `Hostname`, `Port`, `StatusCode`, and `RetryCount` types for configuring and defining network service targets in a type-safe and readable manner. ```rust use waitup::{Port, Hostname, StatusCode, RetryCount, WaitConfig, Target}; use std::time::Duration; // Clear, self-documenting configuration let config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .max_retries(Some(RetryCount::MODERATE.get())) .build(); // Type-safe target construction let database = Target::tcp( Hostname::localhost().as_str(), Port::postgres().get() ).unwrap(); println!("Connecting to {} on port {}", "localhost", if database.port().map(|p| Port::new(p).unwrap().is_system_port()).unwrap_or(false) { "system port" } else { "user port" } ); ``` -------------------------------- ### Create Production and Development Security Configurations Source: https://docs.rs/waitup/1.1.0/waitup/security/struct Provides factory methods for creating pre-configured SecurityValidator instances suitable for production or development environments. 'production()' enforces strict rules, while 'development()' offers a more lenient setup. ```rust let prod_validator = SecurityValidator::production(); let dev_validator = SecurityValidator::development(); ``` -------------------------------- ### Rust Example Usage of assert_ready! Macro Source: https://docs.rs/waitup/latest/src/waitup/macros This Rust code snippet demonstrates how to use the `assert_ready!` macro to check if a TCP target is available. It sets up a vector of `Target` objects and then calls `assert_ready!` with the targets and a specified timeout duration. This example is illustrative and marked `no_run` as it requires a running service to succeed. ```rust use waitup::{assert_ready, Target}; use std::time::Duration; # #[tokio::main] # async fn main() -> Result<(), waitup::WaitForError> { let targets = vec![ Target::tcp("localhost", 8080)?, ]; assert_ready!(targets, timeout: Duration::from_secs(30)); # Ok(()) # } ``` -------------------------------- ### Basic WaitConfig Creation in Rust Source: https://docs.rs/waitup/1.1.0/waitup/config/index Demonstrates the creation of a basic `WaitConfig` using the `WaitConfigBuilder`. This example sets a total timeout and a retry interval. It's suitable for simple use cases where default advanced settings are sufficient. ```rust use waitup::WaitConfig; use std::time::Duration; let config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .interval(Duration::from_secs(1)) .build(); ``` -------------------------------- ### Rust: Advanced Configuration with Cancellation Token using waitup Source: https://docs.rs/waitup/1.1.0/index Demonstrates advanced usage of the waitup crate, including setting timeouts and intervals, and integrating with a cancellation token for graceful shutdown. This example shows how to create a cancellation token, spawn a task to trigger cancellation after a delay, and handle the `Cancelled` error. ```rust use waitup::{Target, WaitConfig, wait_for_connection}; use std::time::Duration; use tokio::time::sleep; #[tokio::main] async fn main() -> Result<(), waitup::WaitForError> { let target = Target::tcp("slow-service", 8080)?; let (builder, cancel_token) = WaitConfig::builder() .timeout(Duration::from_secs(60)) .interval(Duration::from_millis(500)) .with_cancellation(); let config = builder.build(); // Cancel after 10 seconds let cancel_handle = { let token = cancel_token.clone(); tokio::spawn(async move { sleep(Duration::from_secs(10)).await; token.cancel(); }) }; match wait_for_connection(&[target], &config).await { Ok(_) => println!("Service is ready!"), Err(waitup::WaitForError::Cancelled) => println!("Operation was cancelled"), Err(e) => println!("Error: {}", e), } cancel_handle.abort(); // Clean up the cancel task Ok(()) } ``` -------------------------------- ### Initialize WaitConfigBuilder Source: https://docs.rs/waitup/latest/src/waitup/config Provides the default `WaitConfigBuilder` instance, which serves as the starting point for configuring `WaitConfig` settings. It implements the `Default` trait for easy instantiation. ```rust use waitup::WaitConfig; let builder = WaitConfig::builder(); ``` -------------------------------- ### Rust SecurityValidator Production and Development Configurations Source: https://docs.rs/waitup/latest/waitup/security/struct Offers pre-configured instances of `SecurityValidator` suitable for different environments. `production()` provides a strict configuration, while `development()` offers a more lenient setup for development purposes. ```rust pub fn production() -> Self pub fn development() -> Self ``` -------------------------------- ### Wait for Service Connections with Context in Rust Source: https://docs.rs/waitup/latest/waitup/error/index An example of using waitup to asynchronously wait for multiple network services to become available. It demonstrates initializing targets, configuring wait settings, and applying context to the final wait operation. ```rust use waitup::{Target, WaitConfig, wait_for_connection, ResultExt}; use std::time::Duration; async fn wait_for_services() -> Result<(), waitup::WaitForError> { let targets = vec![ Target::tcp("database", 5432) .context("Database target creation failed")?, Target::tcp("cache", 6379) .context("Cache target creation failed")?, ]; let config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .build(); wait_for_connection(&targets, &config) .await .context("Service readiness check failed")?; Ok(()) } ``` -------------------------------- ### Rust: Creating Type-Safe Network Identifiers with waitup Source: https://docs.rs/waitup/latest/waitup/types/index Demonstrates how to create validated `Port` and `Hostname` objects in Rust using the waitup library, including examples for user ports, system ports, dynamic ports, and various hostname formats. ```rust use waitup::{Port, Hostname}; // Create validated ports let port = Port::new(8080).expect("Valid port"); assert_eq!(port.get(), 8080); assert!(port.is_user_port()); // Use port range validation let http_port = Port::http(); assert!(http_port.is_system_port()); let app_port = Port::user_port(8080).expect("8080 is user port"); let ephemeral = Port::dynamic_port(49152).expect("49152 is dynamic"); // Create validated hostnames let hostname = Hostname::new("example.com").expect("Valid hostname"); let localhost = Hostname::localhost(); assert!(localhost.is_localhost()); let ip = Hostname::ipv4("192.168.1.1").expect("Valid IPv4"); assert!(ip.is_ipv4()); ``` -------------------------------- ### Rust: Multiple Services Check with Different Strategies using waitup Source: https://docs.rs/waitup/1.1.0/index Illustrates how to wait for multiple services, including both TCP and HTTP targets, with different strategies using the waitup crate. This example configures waiting for all services to be ready and sets a maximum number of retries. It's useful for orchestrating dependent services. ```rust use waitup::{Target, WaitConfig, wait_for_connection}; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), waitup::WaitForError> { let targets = vec![ Target::tcp("database", 5432)?, Target::tcp("cache", 6379)?, Target::http_url("https://api.example.com/health", 200)?, ]; // Wait for ALL services to be ready let config = WaitConfig::builder() .timeout(Duration::from_secs(120)) .wait_for_any(false) .max_retries(Some(20)) .build(); wait_for_connection(&targets, &config).await?; println!("All services are ready!"); Ok(()) } ``` -------------------------------- ### Build WaitConfig using Builder Pattern in Rust Source: https://docs.rs/waitup/latest/src/waitup/lib This example shows how to construct a `WaitConfig` object using its builder pattern. It illustrates setting various configuration options such as total timeout, check interval, maximum retry interval, and whether to wait for any or all services. This provides flexible control over the waiting behavior. ```rust let config = WaitConfig::builder() .timeout(Duration::from_secs(60)) .interval(Duration::from_secs(2)) .max_interval(Duration::from_secs(30)) .wait_for_any(true) .max_retries(Some(10)) .build(); assert_eq!(config.timeout, Duration::from_secs(60)); assert_eq!(config.initial_interval, Duration::from_secs(2)); ``` -------------------------------- ### Advanced Configuration with Cancellation in Rust using waitup Source: https://docs.rs/waitup/1.1.0/src/waitup/lib Demonstrates advanced configuration of waitup, including enabling cancellation tokens. This example sets up a TCP target, configures a wait strategy with timeout and interval, and uses a separate tokio task to trigger cancellation after a delay. It handles potential `Cancelled` errors. Requires tokio runtime. ```rust use waitup::{Target, WaitConfig, wait_for_connection}; use std::time::Duration; use tokio::time::sleep; #[tokio::main] async fn main() -> Result<(), waitup::WaitForError> { let target = Target::tcp("slow-service", 8080)?; let (builder, cancel_token) = WaitConfig::builder() .timeout(Duration::from_secs(60)) .interval(Duration::from_millis(500)) .with_cancellation(); let config = builder.build(); // Cancel after 10 seconds let cancel_handle = { let token = cancel_token.clone(); tokio::spawn(async move { sleep(Duration::from_secs(10)).await; token.cancel(); }) }; match wait_for_connection(&[target], &config).await { Ok(_) => println!("Service is ready!"), Err(waitup::WaitForError::Cancelled) => println!("Operation was cancelled"), Err(e) => println!("Error: {}", e), } cancel_handle.abort(); // Clean up the cancel task } ``` -------------------------------- ### Domain Knowledge with NewTypes in Rust Source: https://docs.rs/waitup/1.1.0/waitup/types/index Shows how NewType patterns can embed domain-specific knowledge directly into types, enabling more expressive and safer code. Examples demonstrate checking for system ports or success status codes using methods provided by the NewType wrappers. ```rust use waitup::{Port, StatusCode}; let port = Port::http(); if port.is_system_port() { println!("Needs root privileges"); } let status = StatusCode::OK; if status.is_success() { println!("Success!"); } ``` -------------------------------- ### Self-Documenting Code with NewTypes in Rust Source: https://docs.rs/waitup/1.1.0/waitup/types/index Illustrates how NewType wrappers improve code readability by making parameter meanings explicit. Examples show how a function call becomes self-explanatory when using NewTypes, reducing the need to consult external documentation. ```rust let hostname = waitup::Hostname::localhost(); let port = waitup::Port::new(8080).unwrap(); let expected = waitup::StatusCode::OK; let retries = waitup::RetryCount::MODERATE; // Crystal clear what each parameter represents! // (Note: This is illustrative - actual API differs) // check_service(hostname, port, expected, retries); ``` -------------------------------- ### Example Rust waitup::types::Target Usage Source: https://docs.rs/waitup/1.1.0/waitup/types/enum Demonstrates how to create and pattern match on `Target` enum variants in Rust. It shows creating TCP and HTTP targets using helper functions and handling the non-exhaustive nature of the enum during matching. Requires the `waitup` crate. ```rust use waitup::Target; let tcp_target = Target::tcp("localhost", 8080).unwrap(); let http_target = Target::http_url("https://example.com/health", 200).unwrap(); // Pattern matching requires wildcard due to #[non_exhaustive] match tcp_target { Target::Tcp { host, port } => println!("TCP: {}:{}", host.as_str(), port.get()), Target::Http { url, .. } => println!("HTTP: {}", url), _ => {} // Required for external crates } ``` -------------------------------- ### Multiple Target Checks with Strategies Example Source: https://docs.rs/waitup/1.1.0/src/waitup/connection Illustrates checking multiple targets using different strategies. It defines a vector of `Target` instances (TCP and HTTP). The `wait_for_connection` function is used with `WaitConfig` to either wait for all targets to be ready ('Wait for All') or for any single target to be ready ('Wait for Any'). ```rust use waitup::{Target, WaitConfig, wait_for_connection}; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), waitup::WaitForError> { let targets = vec![ Target::tcp("database", 5432)?, Target::tcp("cache", 6379)?, Target::http_url("https://api.example.com/health", 200)?, ]; // Wait for ALL targets to be ready let all_config = WaitConfig::builder() .timeout(Duration::from_secs(60)) .wait_for_any(false) .build(); wait_for_connection(&targets, &all_config).await?; println!("All services are ready!"); // Or wait for ANY target to be ready let any_config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .wait_for_any(true) .build(); wait_for_connection(&targets, &any_config).await?; println!("At least one service is ready!"); Ok(()) } ``` -------------------------------- ### Create Rust waitup Localhost TCP Target Source: https://docs.rs/waitup/1.1.0/waitup/types/enum Provides Rust code examples for creating TCP targets specifically for localhost using `Target::localhost` and `Target::loopback` (IPv4) and `Target::loopback_v6` (IPv6). These functions simplify creating targets for the local machine, accepting a port number and returning a `Result`. ```rust use waitup::Target; let target = Target::localhost(8080)?; ``` ```rust use waitup::Target; let target = Target::loopback(8080)?; ``` ```rust use waitup::Target; let target = Target::loopback_v6(8080)?; ``` -------------------------------- ### Define TCP and HTTP Service Targets in Rust Source: https://docs.rs/waitup/latest/waitup/types/enum Demonstrates how to define TCP and HTTP targets using the `waitup::Target` enum. Includes examples of creating targets and pattern matching on them. Note that pattern matching requires a wildcard arm due to `#[non_exhaustive]`. ```Rust #[non_exhaustive] pub enum Target { Tcp { host: Hostname, port: Port, }, Http { url: Url, expected_status: u16, headers: Option, }, } use waitup::Target; let tcp_target = Target::tcp("localhost", 8080).unwrap(); let http_target = Target::http_url("https://example.com/health", 200).unwrap(); // Pattern matching requires wildcard due to #[non_exhaustive] match tcp_target { Target::Tcp { host, port } => println!("TCP: {}:{}", host.as_str(), port.get()), Target::Http { url, .. } => println!("HTTP: {}", url), _ => {} // Required for external crates } ``` -------------------------------- ### Advanced WaitConfig with Cancellation in Rust Source: https://docs.rs/waitup/1.1.0/waitup/config/index Illustrates advanced `WaitConfig` setup, including setting connection timeouts, maximum retry intervals, maximum retries, and specifying wait-for-any behavior. It also shows how to integrate cancellation tokens for graceful operation shutdown. ```rust use waitup::WaitConfig; use std::time::Duration; let (builder, cancel_token) = WaitConfig::builder() .timeout(Duration::from_secs(60)) .interval(Duration::from_millis(500)) .max_interval(Duration::from_secs(10)) .connection_timeout(Duration::from_secs(5)) .max_retries(Some(20)) .wait_for_any(false) .with_cancellation(); let config = builder.build(); // Later, cancel the operation // cancel_token.cancel(); ``` -------------------------------- ### Handling File Metadata Operations with Result in Rust Source: https://docs.rs/waitup/1.1.0/waitup/error/type Illustrates using Result to handle file system operations like getting metadata, which can fail (e.g., file not found). The example shows checking for success or failure using `is_ok()` and `is_err()`, and inspecting the error kind. ```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); ``` -------------------------------- ### Create HTTP Targets with waitup::http_targets Macro Source: https://docs.rs/waitup/1.1.0/src/waitup/macros The `http_targets!` macro generates a vector of HTTP targets using a URL and expected status code. It returns a `Result, WaitForError>`, providing error handling for invalid inputs. This macro simplifies the setup of HTTP endpoint checks. ```rust macro_rules! http_targets { ($($url:expr => $status:expr),* $(,)?) => { { #[expect(clippy::vec_init_then_push, reason = "macro expansion requires incremental push pattern")] let result = || -> $crate::Result> { let mut targets = Vec::new(); $( targets.push($crate::Target::http_url($url, $status)?); )* return Ok(targets) }; result() } }; } ``` -------------------------------- ### Rust: Test TCP Target Creation Source: https://docs.rs/waitup/latest/src/waitup/lib Tests the creation of `Target::Tcp` instances using both property-based testing with `proptest` and parameterized tests with `test-case`. It verifies that valid hostnames and ports result in successful `Target::tcp` creation and correctly checks the resulting host and port values. ```rust proptest! { #[test] fn test_target_tcp_creation( hostname in "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,30}[a-zA-Z0-9]", port in 1u16..=65535 ) { let result = Target::tcp(hostname, port); assert!(result.is_ok()); } } #[test_case("localhost", 80; "http port")] #[test_case("example.com", 443; "https port")] #[test_case("127.0.0.1", 22; "ssh port")] #[test_case("db.example.com", 5432; "postgres port")] fn test_tcp_target_creation(hostname: &str, port: u16) { let target = Target::tcp(hostname, port).unwrap(); match target { Target::Tcp { host, port: p } => { assert_eq!(host.as_str(), hostname); assert_eq!(p.get(), port); } _ => panic!("Expected TCP target"), } } ``` -------------------------------- ### Rust: Advanced waitup Configuration with Cancellation Token Source: https://docs.rs/waitup/1.1.0/waitup/index Demonstrates advanced waitup configuration, including setting a custom interval and utilizing a cancellation token for graceful shutdown. The example shows how to spawn a task to trigger cancellation after a delay and handle the `Cancelled` error. Requires tokio for async operations and `tokio::time::sleep`. ```rust use waitup::{Target, WaitConfig, wait_for_connection}; use std::time::Duration; use tokio::time::sleep; #[tokio::main] async fn main() -> Result<(), waitup::WaitForError> { let target = Target::tcp("slow-service", 8080)?; let (builder, cancel_token) = WaitConfig::builder() .timeout(Duration::from_secs(60)) .interval(Duration::from_millis(500)) .with_cancellation(); let config = builder.build(); // Cancel after 10 seconds let cancel_handle = { let token = cancel_token.clone(); tokio::spawn(async move { sleep(Duration::from_secs(10)).await; token.cancel(); }) }; match wait_for_connection(&[target], &config).await { Ok(_) => println!("Service is ready!"), Err(waitup::WaitForError::Cancelled) => println!("Operation was cancelled"), Err(e) => println!("Error: {}", e), } cancel_handle.abort(); // Clean up the cancel task Ok(()) } ``` -------------------------------- ### Rust Parameterized Tests: TCP Target Creation Source: https://docs.rs/waitup/1.1.0/src/waitup/lib Uses the `test-case` crate to perform parameterized tests for `Target::tcp` creation with predefined common hostnames and ports (HTTP, HTTPS, SSH, PostgreSQL), verifying the correct construction of the TCP target. ```rust #[test_case("localhost", 80; "http port")] #[test_case("example.com", 443; "https port")] #[test_case("127.0.0.1", 22; "ssh port")] #[test_case("db.example.com", 5432; "postgres port")] fn test_tcp_target_creation(hostname: &str, port: u16) { let target = Target::tcp(hostname, port).unwrap(); match target { Target::Tcp { host, port: p } => { assert_eq!(host.as_str(), hostname); assert_eq!(p.get(), port); } _ => panic!("Expected TCP target"), } } ``` -------------------------------- ### Set Initial Retry Interval for WaitConfigBuilder Source: https://docs.rs/waitup/latest/src/waitup/config Specifies the starting duration between retry attempts with the `interval` method on `WaitConfigBuilder`. This is the base for exponential backoff. ```rust use waitup::WaitConfig; use std::time::Duration; let builder = WaitConfig::builder().interval(Duration::from_millis(500)); ``` -------------------------------- ### Hostname String Representation in Rust Source: https://docs.rs/waitup/latest/src/waitup/types Provides a way to get the hostname as a string slice in Rust. This method is efficient as it avoids any new allocations. ```Rust /// Get the hostname as a string slice #[must_use] #[inline(always)] pub fn as_str(&self) -> &str { &self.0 } ``` -------------------------------- ### Rust: Converting to String with `ToString` Source: https://docs.rs/waitup/latest/waitup/types/struct The `ToString` trait, which requires `Display`, provides the `to_string` method for converting a value into a `String`. This is a common way to get a string representation of various types. ```rust impl ToString for T where T: Display + ?Sized, { fn to_string(&self) -> String; } ``` -------------------------------- ### Test Target Convenience Constructors (Rust) Source: https://docs.rs/waitup/latest/src/waitup/lib Tests convenience constructors for creating `Target` objects for localhost, loopback IPv4, and loopback IPv6 addresses with specified ports. It asserts that the resulting `Target` objects correctly encapsulate the hostname and port information. ```Rust #[test] fn test_target_convenience_constructors() { let localhost_target = Target::localhost(8080).unwrap(); assert_eq!(localhost_target.hostname(), "localhost"); assert_eq!(localhost_target.port(), Some(8080)); let loopback_target = Target::loopback(3000).unwrap(); assert_eq!(loopback_target.hostname(), "127.0.0.1"); assert_eq!(loopback_target.port(), Some(3000)); let loopback_v6_target = Target::loopback_v6(9090).unwrap(); assert_eq!(loopback_v6_target.hostname(), "::1"); assert_eq!(loopback_v6_target.port(), Some(9090)); } ``` -------------------------------- ### Rust: Get Inner Port Value Source: https://docs.rs/waitup/latest/src/waitup/types Provides a method to retrieve the underlying `u16` value of a `Port`. This is an inline, always-called operation for direct access to the port number. ```rust pub const fn get(&self) -> u16 { self.0.get() } ``` -------------------------------- ### Rust Property-Based Tests: TCP Target Creation Source: https://docs.rs/waitup/1.1.0/src/waitup/lib Uses property-based testing to verify the creation of `Target::tcp` instances, ensuring that valid hostname and port combinations result in a successful creation. ```rust proptest! { #[test] fn test_target_tcp_creation( hostname in "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,30}[a-zA-Z0-9]", port in 1u16..=65535 ) { let result = Target::tcp(hostname, port); assert!(result.is_ok()); } } ``` -------------------------------- ### Rust: RateLimiter Request Check Source: https://docs.rs/waitup/1.1.0/src/waitup/security Checks if a request to a target is allowed based on the `RateLimiter`'s configuration. It allows a specified number of requests within a certain time frame and then starts blocking subsequent requests. ```rust #[test] fn test_rate_limiter_allows_normal_requests() { let limiter = RateLimiter::new(5); let target = Target::tcp("localhost", 8080).unwrap(); // Should allow first 5 requests for _ in 0..5 { assert!(limiter.check_rate_limit(&target).is_ok()); } // Should block the 6th request assert!(limiter.check_rate_limit(&target).is_err()); } ``` -------------------------------- ### Create and Configure SecurityValidator Source: https://docs.rs/waitup/1.1.0/waitup/security/struct Demonstrates how to create and configure a SecurityValidator instance. Methods like 'new', 'allow_private_ips', 'allow_localhost', 'allowed_ports', 'blocked_ports', 'max_hostname_length', and 'max_url_length' allow granular control over validation rules. ```rust let validator = SecurityValidator::new() .allow_private_ips(false) .allow_localhost(false) .blocked_ports(vec![23, 67, 68, 161, 162]) .max_hostname_length(255) .max_url_length(2083); ``` -------------------------------- ### Rust: Get Mutable References from Result Source: https://docs.rs/waitup/1.1.0/waitup/error/type Explains the `as_mut` method, which converts a `&mut Result` into a `Result<&mut T, &mut E>`. This enables in-place modification of the contained value within a `Result`. ```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); ``` -------------------------------- ### Rust SmallString Methods: as_str, len, is_empty Source: https://docs.rs/waitup/latest/src/waitup/zero_cost Provides methods to access the string content as a string slice, get its byte length, and check if it's empty. These methods are essential for reading and verifying the state of a `SmallString`. ```rust /// Returns the string contents as a string slice #[must_use] #[inline] pub fn as_str(&self) -> &str { // SAFETY: SmallString maintains the invariant that data[..len] contains only valid UTF-8 // We only construct SmallString from valid UTF-8 strings in try_from_str and push_str unsafe { std::str::from_utf8_unchecked(&self.data[..self.len]) } } /// Returns the length of the string in bytes #[must_use] #[inline] pub const fn len(&self) -> usize { self.len } /// Returns `true` if the string is empty #[must_use] #[inline] pub const fn is_empty(&self) -> bool { self.len == 0 } ``` -------------------------------- ### Test Hostname Constant Constructors (Rust) Source: https://docs.rs/waitup/latest/src/waitup/lib Verifies the functionality of static constructor methods for the `Hostname` struct. It tests `localhost()`, `loopback()`, `loopback_v6()`, and `any()`, asserting that they return `Hostname` objects with the correct string representations for their respective network addresses. ```Rust #[test] fn test_hostname_const_constructors() { let localhost = Hostname::localhost(); assert_eq!(localhost.as_str(), "localhost"); let loopback = Hostname::loopback(); assert_eq!(loopback.as_str(), "127.0.0.1"); let loopback_v6 = Hostname::loopback_v6(); assert_eq!(loopback_v6.as_str(), "::1"); let any = Hostname::any(); assert_eq!(any.as_str(), "0.0.0.0"); } ``` -------------------------------- ### Test TCP Builder Fluent Interface (Rust) Source: https://docs.rs/waitup/latest/src/waitup/lib Demonstrates the fluent interface of the TCP target builder. It shows how to chain methods like `tcp_builder()`, `registered_port()`, and `build()` to construct a `Target` object with a specified hostname and port. It asserts that the built target has the correct hostname and port. ```Rust #[test] fn test_tcp_builder_fluent_interface() { // Test that builder methods return Self for fluent chaining let target = Target::tcp_builder("example.com") .unwrap() .registered_port(8080) .build() .unwrap(); assert_eq!(target.hostname(), "example.com"); assert_eq!(target.port(), Some(8080)); } ``` -------------------------------- ### Basic Target Creation in Rust Source: https://docs.rs/waitup/1.1.0/waitup/target/index Demonstrates the creation of basic TCP and HTTP targets using the `Target` enum. It shows how to specify host, port, and expected HTTP status codes. Dependencies include the 'waitup' and 'url' crates. ```rust use waitup::Target; use url::Url; // Create TCP targets let db = Target::tcp("database.example.com", 5432)?; let localhost_api = Target::localhost(8080)?; // Create HTTP targets let health_check = Target::http_url("https://api.example.com/health", 200)?; let status_page = Target::http( Url::parse("https://status.example.com")?, 200 )?; ``` -------------------------------- ### Create TCP Target Builder Source: https://docs.rs/waitup/1.1.0/waitup/types/enum Creates a builder for TCP targets, starting with a hostname. This method returns a `Result` because the hostname itself might be invalid. The builder can then be used to specify the port and construct the target. ```rust use waitup::Target; let builder = Target::tcp_builder("localhost")?; ``` -------------------------------- ### Rust: Get Immutable References from Result Source: https://docs.rs/waitup/1.1.0/waitup/error/type Demonstrates the `as_ref` method, which converts a `&Result` into a `Result<&T, &E>`. This allows inspecting the contents of a `Result` without taking ownership, leaving the original `Result` unchanged. ```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")); ``` -------------------------------- ### Wait for Multiple Targets (All/Any) with Rust Source: https://docs.rs/waitup/1.1.0/waitup/connection/index Illustrates checking multiple TCP and HTTP targets using different strategies ('Wait for All' and 'Wait for Any') with the waitup crate. It includes configuration for timeouts and specifies the desired strategy. This requires the `waitup` and `tokio` crates. ```rust use waitup::{Target, WaitConfig, wait_for_connection}; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), waitup::WaitForError> { let targets = vec![ Target::tcp("database", 5432)?, Target::tcp("cache", 6379)?, Target::http_url("https://api.example.com/health", 200)?, ]; // Wait for ALL targets to be ready let all_config = WaitConfig::builder() .timeout(Duration::from_secs(60)) .wait_for_any(false) .build(); wait_for_connection(&targets, &all_config).await?; println!("All services are ready!"); // Or wait for ANY target to be ready let any_config = WaitConfig::builder() .timeout(Duration::from_secs(30)) .wait_for_any(true) .build(); wait_for_connection(&targets, &any_config).await?; println!("At least one service is ready!"); Ok(()) } ``` -------------------------------- ### Get Target Hostname Source: https://docs.rs/waitup/1.1.0/waitup/types/enum Extracts the hostname from a `Target` object. This is primarily useful for operational tasks like logging or grouping targets by their host. It returns a string slice (`&str`) referencing the hostname. ```rust let hostname = target.hostname(); ``` -------------------------------- ### SecurityValidator Methods Source: https://docs.rs/waitup/1.1.0/waitup/security/struct Methods available for creating and configuring a SecurityValidator instance. ```APIDOC ## impl SecurityValidator ### `new()` #### Description Create a new security validator with custom settings. #### Method `pub fn new() -> Self` ### `allow_private_ips()` #### Description Allow or disallow private IP addresses. #### Method `pub const fn allow_private_ips(self, allow: bool) -> Self` ### `allow_localhost()` #### Description Allow or disallow localhost connections. #### Method `pub const fn allow_localhost(self, allow: bool) -> Self` ### `allowed_ports()` #### Description Set allowed ports (if None, all ports except blocked are allowed). #### Method `pub fn allowed_ports(self, ports: Option>) -> Self` ### `blocked_ports()` #### Description Set blocked ports. #### Method `pub fn blocked_ports(self, ports: Vec) -> Self` ### `max_hostname_length()` #### Description Set maximum hostname length. #### Method `pub const fn max_hostname_length(self, length: usize) -> Self` ### `max_url_length()` #### Description Set maximum URL length. #### Method `pub const fn max_url_length(self, length: usize) -> Self` ### `validate_target()` #### Description Validate a target against security rules. #### Errors Returns an error if the target fails any security validation checks. #### Method `pub fn validate_target(&self, target: &Target) -> Result<()>` ``` -------------------------------- ### Define TargetResultSliceExt Trait in Rust Source: https://docs.rs/waitup/1.1.0/waitup/iterators/trait Defines the TargetResultSliceExt trait for slices and Vecs of TargetResult. This trait provides methods to get summary statistics, iterate over successful results, and iterate over failed results. It is not dyn compatible. ```rust pub trait TargetResultSliceExt { // Required methods fn summary(&self) -> ResultSummary; fn successful_results(&self) -> impl Iterator; fn failed_results(&self) -> impl Iterator; } ``` -------------------------------- ### Test Target Convenience Constructors in Rust Source: https://docs.rs/waitup/1.1.0/src/waitup/lib Tests convenience methods for creating `Target` objects, such as `localhost`, `loopback`, and `loopback_v6`, with specified ports. It asserts that the hostname and port are correctly set in the resulting `Target` objects. ```rust fn test_target_convenience_constructors() { let localhost_target = Target::localhost(8080).unwrap(); assert_eq!(localhost_target.hostname(), "localhost"); assert_eq!(localhost_target.port(), Some(8080)); let loopback_target = Target::loopback(3000).unwrap(); assert_eq!(loopback_target.hostname(), "127.0.0.1"); assert_eq!(loopback_target.port(), Some(3000)); let loopback_v6_target = Target::loopback_v6(9090).unwrap(); assert_eq!(loopback_v6_target.hostname(), "::1"); assert_eq!(loopback_v6_target.port(), Some(9090)); } ``` -------------------------------- ### Implement ValidatedPort in Rust Source: https://docs.rs/waitup/1.1.0/waitup/zero_cost/type Provides implementations for the `ValidatedPort` struct in Rust, including a constructor `new` that returns an `Option` if the port is within the specified range, and a `get` method to retrieve the port number. This is a Rust-specific implementation. ```rust pub struct WellKnownPort(/* private fields */); impl ValidatedPort { pub const fn new(port: u16) -> Option { // Implementation details... } pub const fn get(&self) -> u16 { // Implementation details... } } ``` -------------------------------- ### Rust Target Parsing and Display Source: https://docs.rs/waitup/1.1.0/src/waitup/lib Shows how to parse string representations into `Target` enums for both TCP and HTTP, and how to display them back into a human-readable format. This is essential for defining services to wait for. ```rust use waitup::Target; use url::Url; #[test] fn test_target_parse_tcp() { let target = Target::parse("localhost:8080", 200).unwrap(); match target { Target::Tcp { host, port } => { assert_eq!(host.as_str(), "localhost"); assert_eq!(port.get(), 8080); } _ => panic!("Expected TCP target"), } } #[test] fn test_target_parse_http() { let target = Target::parse("https://example.com/health", 200).unwrap(); match target { Target::Http { url, expected_status, .. } => { assert_eq!(url.to_string(), "https://example.com/health"); assert_eq!(expected_status, 200); } _ => panic!("Expected HTTP target"), } } #[test] fn test_target_display() { let tcp_target = Target::tcp("localhost", 8080).unwrap(); assert_eq!(tcp_target.display(), "localhost:8080"); let url = Url::parse("https://example.com/health").unwrap(); let http_target = Target::http(url, 200).unwrap(); assert_eq!(http_target.display(), "https://example.com/health"); } ``` -------------------------------- ### PortCategory Enum Definition and Methods in Rust Source: https://docs.rs/waitup/latest/src/waitup/types Defines the PortCategory enum, representing IANA port ranges (System, User, Dynamic). It includes methods to get the string representation and the port range for each category. ```rust /// Port categories as defined by RFC 6335 /// /// This enum represents the three official IANA port range categories. /// The `#[non_exhaustive]` attribute allows for future API evolution /// if additional categories are defined by IANA. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum PortCategory { /// System Ports (0-1023) - Require elevated privileges System, /// User Ports (1024-49151) - Assigned by IANA for applications User, /// Dynamic Ports (49152-65535) - Private/ephemeral use Dynamic, } impl PortCategory { /// Get the string representation of this port category #[must_use] pub const fn as_str(&self) -> &'static str { match self { Self::System => "system", Self::User => "user", Self::Dynamic => "dynamic", } } /// Get the port range for this category #[must_use] pub const fn range(&self) -> (u16, u16) { match self { Self::System => (1, 1023), Self::User => (1024, 49151), Self::Dynamic => (49152, 65535), } } } ``` -------------------------------- ### Test Port Constants (Rust) Source: https://docs.rs/waitup/latest/src/waitup/lib Tests predefined constants for common network ports like SSH, PostgreSQL, MySQL, and Redis. It asserts that the `get()` method of the `Port` enum returns the expected port number for each constant. ```Rust #[test_case(22, Port::ssh(); "ssh port constant")] #[test_case(5432, Port::postgres(); "postgres port constant")] #[test_case(3306, Port::mysql(); "mysql port constant")] #[test_case(6379, Port::redis(); "redis port constant")] fn test_port_constants(expected: u16, port: Port) { assert_eq!(port.get(), expected); } ``` -------------------------------- ### Get Port Category in Rust Source: https://docs.rs/waitup/1.1.0/src/waitup/types Retrieves the RFC 6335 category for a given port (System, User, or Dynamic). This method supports exhaustive pattern matching on port categories. It's inlined for performance. ```rust /// Get the RFC 6335 category for this port /// /// Returns the port category (System, User, or Dynamic) as defined by RFC 6335. /// This method enables exhaustive pattern matching on port categories. /// /// # Examples /// /// ```rust /// use waitup::{Port, PortCategory}; /// /// let http = Port::http(); /// assert_eq!(http.category(), PortCategory::System); /// /// let app_port = Port::new(8080).unwrap(); /// assert_eq!(app_port.category(), PortCategory::User); /// /// let ephemeral = Port::new(50000).unwrap(); /// assert_eq!(ephemeral.category(), PortCategory::Dynamic); /// /// // Pattern matching example /// match http.category() { /// PortCategory::System => println!("Requires elevated privileges"), /// PortCategory::User => println!("Standard application port"), /// PortCategory::Dynamic => println!("Temporary/ephemeral port"), /// _ => {} // Required due to #[non_exhaustive] /// } /// ``` #[must_use] #[inline] pub const fn category(&self) -> PortCategory { let port = self.0.get(); if port <= 1023 { PortCategory::System } else if port <= 49151 { PortCategory::User } else { PortCategory::Dynamic } } ``` -------------------------------- ### Rust SecurityValidator Constructor and Configuration Methods Source: https://docs.rs/waitup/latest/waitup/security/struct Provides methods for creating and configuring a SecurityValidator instance. This includes creating a new validator, enabling/disabling private IP and localhost access, setting allowed and blocked ports, and defining maximum hostname and URL lengths. ```rust pub fn new() -> Self pub const fn allow_private_ips(self, allow: bool) -> Self pub const fn allow_localhost(self, allow: bool) -> Self pub fn allowed_ports(self, ports: Option>) -> Self pub fn blocked_ports(self, ports: Vec) -> Self pub const fn max_hostname_length(self, length: usize) -> Self pub const fn max_url_length(self, length: usize) -> Self ``` -------------------------------- ### SecurityValidator Presets Source: https://docs.rs/waitup/1.1.0/waitup/security/struct Pre-configured security validator instances for different environments. ```APIDOC ## impl SecurityValidator ### `production()` #### Description Strict security configuration for production environments. #### Method `pub fn production() -> Self` ### `development()` #### Description Development-friendly security configuration. #### Method `pub fn development() -> Self` ``` -------------------------------- ### Rust Wait Configuration Builder Source: https://docs.rs/waitup/1.1.0/src/waitup/lib Illustrates how to use the `WaitConfig::builder()` to construct a `WaitConfig` object with custom settings for connection timeouts, intervals, and retry strategies. This allows fine-grained control over the waiting process. ```rust use waitup::WaitConfig; use std::time::Duration; #[test] fn test_wait_config_builder() { let config = WaitConfig::builder() .timeout(Duration::from_secs(60)) .interval(Duration::from_secs(2)) .max_interval(Duration::from_secs(30)) .wait_for_any(true) .max_retries(Some(10)) .build(); assert_eq!(config.timeout, Duration::from_secs(60)); assert_eq!(config.initial_interval, Duration::from_secs(2)); } ``` -------------------------------- ### Rust WaitConfigBuilder Default Implementation Source: https://docs.rs/waitup/latest/waitup/config/struct This Rust code snippet demonstrates the implementation of the `Default` trait for the `WaitConfigBuilder` struct. This allows for creating a default instance of `WaitConfigBuilder` using `WaitConfigBuilder::default()`, providing a convenient starting point for configurations. ```rust impl Default for WaitConfigBuilder { fn default() -> WaitConfigBuilder; } ``` -------------------------------- ### Get Port from Target (Rust) Source: https://docs.rs/waitup/latest/src/waitup/target Retrieves the port number from a target. For TCP targets, it returns the configured port. For HTTP targets, it returns the port from the URL, if specified. This method returns an `Option`, providing the port if available. ```rust pub fn port(&self) -> Option { match self { Self::Tcp { port, .. } => Some(port.get()), Self::Http { url, .. } => url.port(), } } ```