### rsntp Crate Configurations Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Examples of how to configure the rsntp crate in Cargo.toml for different feature sets. ```toml # Standard (all defaults) rsntp = "4" ``` ```toml # Blocking only (remove tokio dependency) rsntp = { version = "4", default-features = false, features = ["chrono"] } ``` ```toml # With time crate support rsntp = { version = "4", features = ["time"] } ``` ```toml # With both chrono and time support rsntp = { version = "4", features = ["chrono", "time"] } ``` -------------------------------- ### Create Default SNTP Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/03-config.md Starts with a Config instance using sensible default values for socket binding, timeouts, and connection behavior. ```rust use rsntp::Config; let config = Config::default(); ``` -------------------------------- ### Using LeapIndicator with SntpClient Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/07-types.md Demonstrates how to use the SntpClient to synchronize with an NTP server and handle the LeapIndicator returned in the synchronization result. This example shows a typical match statement for processing the leap indicator. ```rust use rsntp::{SntpClient, LeapIndicator}; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); match result.leap_indicator() { LeapIndicator::NoWarning => { /* normal operation */ }, LeapIndicator::LastMinuteHas61Seconds => { /* prepare for leap second insertion */ }, LeapIndicator::LastMinuteHas59Seconds => { /* prepare for leap second deletion */ }, LeapIndicator::AlarmCondition => { /* server not synchronized */ }, } ``` -------------------------------- ### ToServerAddrs Usage Examples Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/07-types.md Illustrates various ways to use the ToServerAddrs trait with SntpClient, including hostnames, IP addresses, and explicit port specifications. Shows flexibility in providing server addresses. ```rust use rsntp::{SntpClient, ToServerAddrs}; let client = SntpClient::new(); // All these are valid: client.synchronize("pool.ntp.org").unwrap(); client.synchronize("192.168.1.1:456").unwrap(); client.synchronize(("pool.ntp.org", 123)).unwrap(); client.synchronize("127.0.0.1").unwrap(); use std::net::Ipv4Addr; client.synchronize(Ipv4Addr::new(127, 0, 0, 1)).unwrap(); ``` -------------------------------- ### Configure IPv6 Bind Address Source: https://github.com/dobaksz/rsntp/blob/master/README.md Set an IPv6 bind address for the SNTP client to enable synchronization with IPv6 servers. This example also shows how to get the Unix timestamp. ```rust use rsntp::{Config, SntpClient}; use std::net::Ipv6Addr; let config = Config::default().bind_address((Ipv6Addr::UNSPECIFIED, 0).into()); let client = SntpClient::with_config(config); let result = client.synchronize("2.pool.ntp.org").unwrap(); let unix_timestamp_utc = result.datetime().unix_timestamp(); ``` -------------------------------- ### Synchronize Time with Async API Source: https://github.com/dobaksz/rsntp/blob/master/README.md Use the asynchronous API with Tokio to get the current time from an NTP server. Requires the chrono crate. ```rust use rsntp::AsyncSntpClient; use chrono::{DateTime, Local, Utc}; async fn local_time() -> DateTime { let client = AsyncSntpClient::new(); let result = client.synchronize("pool.ntp.org").await.unwrap(); DateTime::from(result.datetime().into_chrono_datetime().unwrap()) } ``` -------------------------------- ### Synchronize Time with Blocking API Source: https://github.com/dobaksz/rsntp/blob/master/README.md Use the synchronous API to get the current time from an NTP server. Requires the chrono crate. ```rust use rsntp::SntpClient; use chrono::{DateTime, Local}; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let local_time: DateTime = DateTime::from(result.datetime().into_chrono_datetime().unwrap()); println!("Current time is: {}", local_time); ``` -------------------------------- ### Convert SynchronizationResult to chrono DateTime Source: https://github.com/dobaksz/rsntp/blob/master/README.md Example of converting the result from SynchronizationResult to a chrono DateTime object after API changes in v3.0. ```rust let datetime = result.datetime().into_chrono_datetime().unwrap(); ``` -------------------------------- ### Get Reference Identifier Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Retrieves the server's reference identifier, which indicates the synchronization source. This can be an ASCII string for primary servers or an IPv4 address for secondary servers. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); println!("Time source: {}", result.reference_identifier()); ``` -------------------------------- ### Get Clock Offset Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Retrieves the signed offset between the server and local clock. Use this to determine if the local clock is ahead or behind the server. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let offset = result.clock_offset().as_secs_f64(); if offset > 0.0 { println!("Local clock is {} seconds behind", offset); } else { println!("Local clock is {} seconds ahead", -offset); } ``` -------------------------------- ### Get Stratum Level Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Retrieves the server's stratum level in the NTP hierarchy. Stratum 1 indicates a primary reference, while levels 2-15 indicate secondary references. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); match result.stratum() { 1 => println!("Primary time source"), 2..=15 => println!("Secondary source (stratum {})", result.stratum()), _ => println!("Unsynchronized or invalid"), } ``` -------------------------------- ### Get UTC Time with OffsetDateTime Source: https://github.com/dobaksz/rsntp/blob/master/README.md Retrieve UTC time from SynchronizationResult using the into_offset_date_time method. This example assumes the 'chrono' feature is enabled. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let utc_time = result .datetime() .into_offset_date_time() .unwrap(); println!("UTC time is: {}", utc_time); ``` -------------------------------- ### Build and Use SNTP Client with Custom Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/03-config.md Demonstrates chaining multiple configuration methods to create a custom Config object and then initializing an SntpClient with it. ```rust use rsntp::{Config, SntpClient}; use std::time::Duration; let config = Config::default() .bind_address("192.168.0.1:0".parse().unwrap()) .timeout(Duration::from_secs(10)) .connect_ip(true); let client = SntpClient::with_config(config); ``` -------------------------------- ### Configuration Persistence Approaches Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/09-configuration.md Demonstrates two approaches for changing client configuration: creating a new client with a new Config, or modifying an existing mutable client using setter methods before synchronization. ```rust use rsntp::SntpClient; use std::time::Duration; // Approach 1: Create new client with new config let client1 = SntpClient::new(); let config = rsntp::Config::default().timeout(Duration::from_secs(10)); let client2 = SntpClient::with_config(config); // Approach 2: Modify existing mutable client let mut client = SntpClient::new(); client.set_timeout(Duration::from_secs(10)); let _ = client.synchronize("pool.ntp.org"); ``` -------------------------------- ### Build Fully Customized Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/09-configuration.md Create a client with a fully customized configuration, including bind address, timeout, and connect IP settings. Alternatively, modify an existing mutable client using setter methods. ```rust use rsntp::{Config, SntpClient}; use std::net::Ipv6Addr; use std::time::Duration; // Build a fully customized config let config = Config::default() .bind_address((Ipv6Addr::UNSPECIFIED, 0).into()) .timeout(Duration::from_secs(15)) .connect_ip(true); // Create client with this config let client = SntpClient::with_config(config); // Or modify existing client let mut client = SntpClient::new(); client.set_bind_address("192.168.1.100:0".parse().unwrap()); client.set_timeout(Duration::from_secs(5)); ``` -------------------------------- ### Get Sign of Duration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/06-sntp-duration.md Returns the sign of the duration. Returns 1 for positive durations and -1 for negative durations. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let offset = result.clock_offset(); match offset.signum() { 1 => println!("Local clock is behind"), -1 => println!("Local clock is ahead"), _ => unreachable!(), } ``` -------------------------------- ### Config Builder Methods Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Demonstrates building a custom SNTP client configuration using various builder methods. ```rust let config = Config::default() .bind_address(Some(bind_addr)) .timeout(Duration::from_secs(5)) .connect_ip(ip_addr); ``` -------------------------------- ### AsyncSntpClient::new Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/02-async-sntp-client.md Creates a new AsyncSntpClient instance with default configuration. The default configuration includes binding to 0.0.0.0:0, a timeout of 3 seconds, and enabling connect IP. ```APIDOC ## AsyncSntpClient::new ### Description Creates a new instance with default configuration. **Default configuration:** - Bind address: `0.0.0.0:0` (IPv4) - Timeout: 3 seconds - Connect IP: true ### Returns A new `AsyncSntpClient` instance ### Example ```rust use rsntp::AsyncSntpClient; let client = AsyncSntpClient::new(); ``` ``` -------------------------------- ### Create New AsyncSntpClient Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/02-async-sntp-client.md Creates a new AsyncSntpClient instance with default configuration. Default settings include binding to 0.0.0.0:0 (IPv4), a timeout of 3 seconds, and enabling connect IP. ```rust use rsntp::AsyncSntpClient; let client = AsyncSntpClient::new(); ``` -------------------------------- ### Create New SntpClient Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/01-sntp-client.md Creates a new SntpClient instance with default configuration. The default configuration includes binding to 0.0.0.0:0 (IPv4), a timeout of 3 seconds, and enabling connect IP. ```rust use rsntp::SntpClient; let client = SntpClient::new(); ``` -------------------------------- ### Get Duration as f64 Seconds Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/06-sntp-duration.md Returns the duration as a floating-point number of seconds, preserving sign. Negative values indicate the duration is negative. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let offset_secs = result.clock_offset().as_secs_f64(); println!("Offset: {} seconds", offset_secs); ``` -------------------------------- ### AsyncSntpClient::with_config Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/02-async-sntp-client.md Creates a new AsyncSntpClient instance with a custom configuration provided by a Config object. This allows for fine-tuning of client behavior like timeouts. ```APIDOC ## AsyncSntpClient::with_config ### Description Creates a new instance with custom configuration. ### Parameters #### Request Body - **config** (`Config`) - Required - Client configuration object ### Returns A new `AsyncSntpClient` instance ### Example ```rust use rsntp::{Config, AsyncSntpClient}; use std::time::Duration; let config = Config::default() .timeout(Duration::from_secs(10)); let client = AsyncSntpClient::with_config(config); ``` ``` -------------------------------- ### AsyncSntpClient Constructors Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Illustrates the creation of a new asynchronous SNTP client, with options for default or custom configurations. ```rust let client = AsyncSntpClient::new(); let client = AsyncSntpClient::with_config(config); ``` -------------------------------- ### Get Leap Indicator Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Retrieves the server's leap second warning. This indicates if a leap second adjustment is scheduled for the end of the current day. ```rust use rsntp::{SntpClient, LeapIndicator}; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); match result.leap_indicator() { LeapIndicator::NoWarning => println!("No leap second scheduled"), LeapIndicator::LastMinuteHas61Seconds => println!("Leap second insertion coming"), LeapIndicator::LastMinuteHas59Seconds => println!("Leap second deletion coming"), LeapIndicator::AlarmCondition => println!("Clock not synchronized"), } ``` -------------------------------- ### SntpClient::new Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/01-sntp-client.md Creates a new SNTP client instance with default configuration. The default configuration includes binding to 0.0.0.0:0, a timeout of 3 seconds, and enabling connect IP. ```APIDOC ## SntpClient::new ### Description Creates a new instance with default configuration. **Default configuration:** - Bind address: `0.0.0.0:0` (IPv4) - Timeout: 3 seconds - Connect IP: true ### Returns A new `SntpClient` instance ### Example ```rust use rsntp::SntpClient; let client = SntpClient::new(); ``` ``` -------------------------------- ### Get Current UTC Datetime Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Retrieves the current UTC date and time based on the synchronized offset. Use this value immediately after retrieval for accuracy. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); // Convert to Unix timestamp let unix_secs = result.datetime().unix_timestamp().unwrap(); // With chrono support (default feature) #[cfg(feature = "chrono")] { let utc: chrono::DateTime = result.datetime().try_into().unwrap(); println!("UTC: {}", utc); } ``` -------------------------------- ### Get Round-Trip Delay Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Retrieves the round-trip network delay for SNTP packets. This value is always positive and represents the time for packets to travel to the server and back. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let rtt_ms = result.round_trip_delay().as_secs_f64() * 1000.0; println!("Network RTT: {:.2} ms", rtt_ms); ``` -------------------------------- ### Custom NTP Client Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Illustrates configuring the SntpClient with a custom configuration, including bind address and timeout, before synchronizing time. ```rust use rsntp::{Config, SntpClient}; use std::time::Duration; use std::net::Ipv6Addr; let config = Config::default() .bind_address((Ipv6Addr::UNSPECIFIED, 0).into()) .timeout(Duration::from_secs(10)); let client = SntpClient::with_config(config); let result = client.synchronize("2.pool.ntp.org")?; ``` -------------------------------- ### SntpClient Constructors Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Demonstrates how to create a new blocking SNTP client instance, either with default configuration or a custom one. ```rust let client = SntpClient::new(); let client = SntpClient::with_config(config); ``` -------------------------------- ### Get Unix Timestamp from SntpDateTime Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/05-sntp-datetime.md Retrieves the duration since the Unix epoch. Assumes system clock stability. Use when you need seconds since January 1, 1970. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let unix_ts = result.datetime().unix_timestamp().unwrap(); println!("Seconds since epoch: {}", unix_ts.as_secs()); ``` -------------------------------- ### Create AsyncSntpClient with Custom Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/02-async-sntp-client.md Creates a new AsyncSntpClient instance with a custom configuration object. This allows overriding default settings like the timeout duration. ```rust use rsntp::{Config, AsyncSntpClient}; use std::time::Duration; let config = Config::default() .timeout(Duration::from_secs(10)); let client = AsyncSntpClient::with_config(config); ``` -------------------------------- ### SntpClient::with_config Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/01-sntp-client.md Creates a new SNTP client instance with a custom configuration object. This allows for fine-grained control over client behavior such as timeouts. ```APIDOC ## SntpClient::with_config ### Description Creates a new instance with custom configuration. ### Parameters #### Request Body - **config** (`Config`) - Required - Client configuration object ### Returns A new `SntpClient` instance ### Example ```rust use rsntp::{Config, SntpClient}; use std::time::Duration; let config = Config::default() .timeout(Duration::from_secs(10)); let client = SntpClient::with_config(config); ``` ``` -------------------------------- ### Get Absolute Duration as std::time::Duration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/06-sntp-duration.md Returns the absolute value of the duration as std::time::Duration. This method returns the unsigned magnitude, as std::time::Duration cannot represent negative values. It may return an error if the duration magnitude is too large. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let offset = result.clock_offset(); let abs_dur = offset.abs_as_std_duration().unwrap(); let sign = offset.signum(); println!( "Clock offset: {} {:?}", if sign > 0 { "+" } else { "-" }, abs_dur ); ``` -------------------------------- ### Asynchronous NTP Client Synchronization Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Shows how to use the asynchronous AsyncSntpClient within a tokio runtime to synchronize time and print the clock offset. ```rust use rsntp::AsyncSntpClient; #[tokio::main] async fn main() { let client = AsyncSntpClient::new(); let result = client.synchronize("pool.ntp.org").await?; println!("Clock offset: {} seconds", result.clock_offset().as_secs_f64()); } ``` -------------------------------- ### Synchronize with NTP Servers using Various Address Formats Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/10-to-server-addrs.md This snippet shows how to use the `SntpClient::synchronize` method with different types of server addresses. It covers string hostnames, hostnames with explicit ports, IPv4 and IPv6 addresses, IP address tuples with ports, direct IP address types, SocketAddr, and string tuples with ports. ```rust use rsntp::SntpClient; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; let client = SntpClient::new(); // String hostname client.synchronize("pool.ntp.org").unwrap(); // String with explicit port client.synchronize("pool.ntp.org:12345").unwrap(); // IPv4 address client.synchronize("192.168.1.1").unwrap(); // IPv6 address client.synchronize("::1").unwrap(); client.synchronize("[::1]").unwrap(); // IP tuples client.synchronize((Ipv4Addr::new(192, 168, 1, 1), 456)).unwrap(); client.synchronize((Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 456)).unwrap(); // Direct IP types let ipv4 = Ipv4Addr::new(192, 168, 1, 1); client.synchronize(ipv4).unwrap(); let ipv6 = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1); client.synchronize(ipv6).unwrap(); // SocketAddr let addr: SocketAddr = "192.168.1.1:456".parse().unwrap(); client.synchronize(addr).unwrap(); // Tuples with port client.synchronize(("pool.ntp.org", 456)).unwrap(); client.synchronize(("192.168.1.1".to_string(), 456)).unwrap(); ``` -------------------------------- ### Create SntpClient with Custom Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/01-sntp-client.md Creates a new SntpClient instance using a custom Config object. This allows for fine-tuning parameters like the timeout duration. ```rust use rsntp::{Config, SntpClient}; use std::time::Duration; let config = Config::default() .timeout(Duration::from_secs(10)); let client = SntpClient::with_config(config); ``` -------------------------------- ### AsyncSntpClient Methods Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Details the asynchronous methods for synchronizing time and modifying client settings. ```rust client.synchronize().await?; client.set_timeout(Duration::from_secs(5)); client.set_bind_address(Some(bind_addr)); client.set_config(config); ``` -------------------------------- ### Asynchronous SNTP Synchronization Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/00-START-HERE.md Demonstrates how to perform SNTP synchronization asynchronously using the AsyncSntpClient. Requires an async runtime like tokio. ```rust use rsntp::AsyncSntpClient; #[tokio::main] async fn main() { let client = AsyncSntpClient::new(); let result = client.synchronize("pool.ntp.org").await?; println!("Async offset: {}", result.clock_offset().as_secs_f64()); } ``` -------------------------------- ### Default Configuration Values Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/09-configuration.md Illustrates the default values for rsntp configuration, including bind address, timeout, and connect IP settings. These defaults are equivalent to the specified values. ```rust use rsntp::Config; use std::time::Duration; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; let defaults = Config::default(); // Equivalent to: // bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0) // timeout: Duration::from_secs(3) // connect_ip: true ``` -------------------------------- ### AsyncSntpClient::set_config Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/02-async-sntp-client.md Replaces the entire current client configuration with a new `Config` object. This is useful for applying a set of configuration options at once. ```APIDOC ## set_config ### Description Replaces the entire client configuration. ### Parameters #### Request Body - **config** (`Config`) - Required - New configuration ### Example ```rust use rsntp::{Config, AsyncSntpClient}; let mut client = AsyncSntpClient::new(); let new_config = Config::default(); client.set_config(new_config); ``` ``` -------------------------------- ### TryInto chrono::Duration and into_chrono_duration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/06-sntp-duration.md Demonstrates converting SntpDuration to chrono::Duration using both TryInto and the preferred into_chrono_duration method. The into_chrono_duration method avoids needing explicit type annotations. ```rust use rsntp::SntpClient; use std::convert::TryInto; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); // Using try_into with explicit type let chrono_dur: chrono::Duration = result.clock_offset().try_into()?; // Using into_chrono_duration (preferred, no annotation needed) let chrono_dur = result.clock_offset().into_chrono_duration()?; ``` -------------------------------- ### Synchronize with NTP Server and Handle Errors Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/08-errors.md Demonstrates how to use SntpClient to synchronize time with an NTP server, handling common errors like protocol issues, I/O errors (including timeouts), and other synchronization failures. This snippet is useful for robust network time synchronization applications. ```rust use rsntp::{SntpClient, SynchronizationError, ProtocolError}; use std::time::Duration; let mut client = SntpClient::new(); client.set_timeout(Duration::from_secs(5)); loop { match client.synchronize("pool.ntp.org") { Ok(result) => { println!("Synchronized: offset = {} seconds", result.clock_offset().as_secs_f64()); break; } Err(SynchronizationError::ProtocolError( ProtocolError::KissODeath(_))) => { eprintln!("Server rejected request - stopping"); break; } Err(SynchronizationError::IOError(e)) if e.kind() == std::io::ErrorKind::TimedOut => { eprintln!("Timeout - retrying"); std::thread::sleep(Duration::from_secs(1)); } Err(e) => { eprintln!("Synchronization failed: {}", e); break; } } } ``` -------------------------------- ### TryInto Implementations Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/06-sntp-duration.md SntpDuration implements TryInto for chrono::Duration and time::Duration, providing convenient conversion methods. ```APIDOC ## TryInto Implementations `SntpDuration` implements `TryInto` for: - `chrono::Duration` (requires `chrono` feature) - `time::Duration` (requires `time` feature) ### Example ```rust use rsntp::SntpClient; use std::convert::TryInto; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); // Using try_into with explicit type let chrono_dur: chrono::Duration = result.clock_offset().try_into()?; // Using into_chrono_duration (preferred, no annotation needed) let chrono_dur = result.clock_offset().into_chrono_duration()?; ``` ``` -------------------------------- ### SntpClient Methods Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Shows common methods available on the blocking SNTP client for synchronization and configuration adjustments. ```rust client.synchronize()?; client.set_timeout(Duration::from_secs(5)); client.set_bind_address(Some(bind_addr)); client.set_config(config); ``` -------------------------------- ### Synchronize with NTP Server (Blocking) Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/00-START-HERE.md Use this snippet to perform a blocking synchronization with an NTP server. Ensure you have imported the `SntpClient`. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org")?; println!("Offset: {} seconds", result.clock_offset().as_secs_f64()); ``` -------------------------------- ### Config Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Configuration builder for SNTP clients. Allows customization of network parameters like bind address and timeouts. ```APIDOC ## Config Struct ### Description Used to build and customize the configuration for SNTP clients. ### Methods - `default()`: Returns a `Config` with default settings. - `bind_address(addr: SocketAddr)`: Sets the local address to bind to. - `timeout(duration: Duration)`: Sets the network timeout for requests. - `connect_ip(ip: IpAddr)`: Sets the IP address of the SNTP server to connect to. ### Options Table Contains a detailed table of configuration options with their types and default values. ### Examples Includes 8+ examples showcasing different configuration setups. ``` -------------------------------- ### Configure Connect IP Setting Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/09-configuration.md Control whether the UDP socket is connected to the server address before sending. Setting this to `false` uses `send_to()` / `recv_from()` without connection, which may be necessary for some network configurations. ```rust use rsntp::{Config, SntpClient}; let config = Config::default() .connect_ip(false); let client = SntpClient::with_config(config); ``` -------------------------------- ### Configure SntpClient for IPv6 Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/00-START-HERE.md Set the bind address for the `SntpClient` to use IPv6, allowing it to listen on any available IPv6 interface. Import `Config`, `SntpClient`, and `Ipv6Addr`. ```rust use rsntp::{Config, SntpClient}; use std::net::Ipv6Addr; let config = Config::default() .bind_address((Ipv6Addr::UNSPECIFIED, 0).into()); let client = SntpClient::with_config(config); ``` -------------------------------- ### NTP Synchronization Error Handling Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Demonstrates how to handle potential errors during NTP synchronization, specifically catching ProtocolError::KissODeath and other general synchronization errors. ```rust use rsntp::{SntpClient, SynchronizationError, ProtocolError}; let client = SntpClient::new(); match client.synchronize("pool.ntp.org") { Ok(result) => { println!("Offset: {} seconds", result.clock_offset().as_secs_f64()); } Err(SynchronizationError::ProtocolError( ProtocolError::KissODeath(code))) => { eprintln!("Server rejected request: {}", code); } Err(e) => { eprintln!("Synchronization failed: {}", e); } } ``` -------------------------------- ### Configure Bind Address for IPv4 and IPv6 Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/09-configuration.md Customize the local socket address for the UDP client. Set the port to 0 to let the OS choose an available port. Use an IPv6 address to communicate with IPv6 NTP servers. ```rust use rsntp::{Config, SntpClient}; use std::net::Ipv6Addr; // For IPv4 servers (default) let config = Config::default(); // For IPv6 servers let config = Config::default() .bind_address((Ipv6Addr::UNSPECIFIED, 0).into()); let client = SntpClient::with_config(config); ``` -------------------------------- ### SntpClient::set_config Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/01-sntp-client.md Replaces the entire current client configuration with a new `Config` object. This is useful for applying a set of configuration changes at once. ```APIDOC ## set_config ### Description Replaces the entire client configuration. ### Parameters #### Request Body - **config** (`Config`) - Required - New configuration ### Example ```rust use rsntp::{Config, SntpClient}; let mut client = SntpClient::new(); let new_config = Config::default(); client.set_config(new_config); ``` ``` -------------------------------- ### Using ReferenceIdentifier with SntpClient Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/07-types.md Demonstrates how to retrieve and interpret the reference identifier from an NTP synchronization result. Handles different types of identifiers like ASCII, IP addresses, and MD5 hashes. ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); match result.reference_identifier() { rsntp::ReferenceIdentifier::ASCII(s) => println!("Primary: {}", s), rsntp::ReferenceIdentifier::IpAddress(addr) => println!("Secondary IPv4: {}", addr), rsntp::ReferenceIdentifier::MD5Hash(h) => println!("Secondary IPv6: {:#X}", h), _ => println!("Unknown"), } ``` -------------------------------- ### Add rsntp to Cargo.toml Source: https://github.com/dobaksz/rsntp/blob/master/README.md Add the rsntp crate to your project's dependencies in Cargo.toml. ```toml [dependencies] rsntp = "4.1.2" ``` -------------------------------- ### Replace AsyncSntpClient Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/02-async-sntp-client.md Replaces the entire configuration of an existing AsyncSntpClient instance with a new Config object. This allows for a complete reconfiguration of the client's behavior. ```rust use rsntp::{Config, AsyncSntpClient}; let mut client = AsyncSntpClient::new(); let new_config = Config::default(); client.set_config(new_config); ``` -------------------------------- ### Using TryInto for Chrono DateTime Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/05-sntp-datetime.md Demonstrates converting SntpDateTime to chrono::DateTime using the TryInto trait. This method is available when the 'chrono' feature is enabled. ```rust use rsntp::SntpClient; use std::convert::TryInto; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); // Using try_into with type annotation let utc: chrono::DateTime = result.datetime().try_into()?; // Using into_* method (no type annotation needed) let utc = result.datetime().into_chrono_datetime()?; ``` -------------------------------- ### Server Address Resolution Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Explains the `ToServerAddrs` trait, which allows flexible specification of NTP server addresses. ```APIDOC ## ToServerAddrs Trait ### Description The `ToServerAddrs` trait provides a flexible way to specify NTP server addresses. Implementations of this trait can be used wherever a server address is required by the rsntp client. ### Supported Types This trait is implemented for, and accepts, the following types: - `&str` (e.g., `"pool.ntp.org"`) - `String` - `IpAddr` - `Ipv4Addr` - `Ipv6Addr` - `SocketAddr` - Tuples specifying host and port (e.g., `("pool.ntp.org", 456)`) ``` -------------------------------- ### SntpDateTime Conversions Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Illustrates converting the SNTP date-time type into various standard Rust and chrono formats. ```rust let unix_ts = sntp_dt.unix_timestamp(); let sys_time = sntp_dt.into_system_time(); let chrono_dt = sntp_dt.into_chrono_datetime(); let offset_dt = sntp_dt.into_offset_date_time(); ``` -------------------------------- ### Disable Async API and Enable Chrono Source: https://github.com/dobaksz/rsntp/blob/master/README.md Configure Cargo.toml to disable the default asynchronous API and explicitly enable the 'chrono' feature. ```toml [dependencies] rsntp = { version = "4.1.2", default-features = false, features = ["chrono"] } ``` -------------------------------- ### SNTP Synchronization with Error Handling Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/00-START-HERE.md Shows how to handle potential errors during SNTP synchronization, including specific handling for ProtocolError::KissODeath. ```rust use rsntp::{SntpClient, SynchronizationError, ProtocolError}; let client = SntpClient::new(); match client.synchronize("pool.ntp.org") { Ok(result) => println!("Success: {}", result.clock_offset().as_secs_f64()), Err(SynchronizationError::ProtocolError( ProtocolError::KissODeath(code))) => { eprintln!("Server rejected ({}), will not retry", code); } Err(e) => eprintln!("Failed: {}", e), } ``` -------------------------------- ### TryInto Implementations Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/05-sntp-datetime.md SntpDateTime implements the TryInto trait for seamless conversion into std::time::SystemTime, chrono::DateTime (with chrono feature), and time::OffsetDateTime (with time feature). This allows using the `?` operator or `try_into()` for fallible conversions. ```APIDOC ## TryInto Implementations `SntpDateTime` implements `TryInto` for: - `std::time::SystemTime` (always available) - `chrono::DateTime` (requires `chrono` feature) - `time::OffsetDateTime` (requires `time` feature) This allows using the `?` operator or `try_into()` directly: ```rust use rsntp::SntpClient; use std::convert::TryInto; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); // Using try_into with type annotation let utc: chrono::DateTime = result.datetime().try_into()?; // Using into_* method (no type annotation needed) let utc = result.datetime().into_chrono_datetime()?; ``` ``` -------------------------------- ### (Ipv6Addr, u16) Implementation for ToServerAddrs Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/10-to-server-addrs.md Allows an (Ipv6Addr, u16) tuple to be used with ToServerAddrs. The explicit port in the tuple is always used. ```rust use rsntp::SntpClient; use std::net::Ipv6Addr; let addr = (Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 456); let client = SntpClient::new(); client.synchronize(addr).unwrap(); // Uses port 456 ``` -------------------------------- ### into_chrono_duration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/06-sntp-duration.md Convenience wrapper for converting to chrono::Duration (requires chrono feature). Avoids needing explicit type annotations. ```APIDOC ## into_chrono_duration ### Description Convenience wrapper for converting to `chrono::Duration` (requires `chrono` feature). ### Returns `Result` ### Throws/Rejects - `ConversionError::Overflow` — Cannot be represented as Duration ### Example ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let chrono_dur = result.clock_offset().into_chrono_duration().unwrap(); println!("Offset: {}", chrono_dur); ``` ``` -------------------------------- ### Convert SynchronizationResult to chrono DateTime using TryInto Source: https://github.com/dobaksz/rsntp/blob/master/README.md Alternative conversion of SynchronizationResult to a chrono DateTime using the TryInto trait. ```rust let datetime: chrono::DateTime = result.datetime().try_into().unwrap(); ``` -------------------------------- ### SntpDuration Conversions Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Demonstrates converting the SNTP duration type into different standard duration representations. ```rust let secs = sntp_dur.as_secs_f64(); let sign = sntp_dur.signum(); let std_dur = sntp_dur.abs_as_std_duration(); let chrono_dur = sntp_dur.into_chrono_duration(); let time_dur = sntp_dur.into_time_duration(); ``` -------------------------------- ### (Ipv4Addr, u16) Implementation for ToServerAddrs Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/10-to-server-addrs.md Allows an (Ipv4Addr, u16) tuple to be used with ToServerAddrs. The explicit port in the tuple is always used. ```rust use rsntp::SntpClient; use std::net::Ipv4Addr; let addr = (Ipv4Addr::new(192, 168, 1, 1), 456); let client = SntpClient::new(); client.synchronize(addr).unwrap(); // Uses port 456 ``` -------------------------------- ### reference_identifier Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Returns the server's reference identifier, which indicates the synchronization source. This can be an ASCII string for primary servers or an IPv4 address for secondary servers. ```APIDOC ## reference_identifier ### Description Returns the server's reference identifier (synchronization source). For primary servers (stratum 1), this is a 4-character ASCII string. For secondary IPv4 servers, it's an IPv4 address. For IPv6 servers, it's the first 32 bits of the MD5 hash of the IPv6 address. ### Returns Reference to `ReferenceIdentifier` ### Example ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); println!("Time source: {}", result.reference_identifier()); ``` ``` -------------------------------- ### AsyncSntpClient (Async) Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt The asynchronous SNTP client interface for synchronizing time. It is suitable for non-blocking applications and integrates with async runtimes. ```APIDOC ## AsyncSntpClient (Async) ### Description Provides an asynchronous interface for SNTP client operations. Ideal for use in async Rust applications. ### Constructors - `new()`: Creates a new `AsyncSntpClient` with default configuration. - `with_config(config: Config)`: Creates a new `AsyncSntpClient` with a provided `Config` object. ### Methods - `async synchronize()`: Asynchronously initiates an SNTP synchronization request and returns the result. - `set_timeout(duration: Duration)`: Sets the timeout for synchronization attempts. - `set_bind_address(addr: SocketAddr)`: Sets the local address to bind to for outgoing requests. - `set_config(config: Config)`: Updates the client's configuration with a new `Config` object. ### Examples Provides 10+ production-ready examples demonstrating various usage scenarios. ``` -------------------------------- ### Date/Time Wrapper Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Details the `SntpDateTime` wrapper, providing methods for accessing and converting SNTP timestamp information. ```APIDOC ## SntpDateTime ### Description The `SntpDateTime` type is a wrapper around SNTP timestamp information, offering various methods for accessing and converting the date and time. ### Methods - **`unix_timestamp()`** - Description: Returns the timestamp as the number of seconds since the Unix epoch (January 1, 1970). - **`into_system_time()`** - Description: Converts the `SntpDateTime` into a `std::time::SystemTime` object. - **`into_chrono_datetime()`** - Description: Converts the `SntpDateTime` into a `chrono::DateTime` object. Requires the `chrono` feature. - **`into_offset_date_time()`** - Description: Converts the `SntpDateTime` into a `time::OffsetDateTime` object. Requires the `time` feature. ``` -------------------------------- ### rsntp Feature Flags Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/00-START-HERE.md Configure rsntp dependencies using feature flags in your Cargo.toml. The minimal configuration excludes async and chrono features. ```toml # Minimal (blocking only, no chrono) rsntp = { version = "4", default-features = false } ``` ```toml # Standard (default) rsntp = "4" ``` ```toml # With time crate support rsntp = { version = "4", features = ["time"] } ``` ```toml # Blocking only (no tokio) rsntp = { version = "4", default-features = false, features = ["chrono"] } ``` -------------------------------- ### Configure Timeout Duration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/09-configuration.md Set the duration to wait for a server response. Recommended values vary based on network reliability. This can be set during configuration or on an existing mutable client. ```rust use rsntp::{Config, SntpClient}; use std::time::Duration; let config = Config::default() .timeout(Duration::from_secs(10)); let client = SntpClient::with_config(config); // Or on existing client let mut client = SntpClient::new(); client.set_timeout(Duration::from_secs(5)); ``` -------------------------------- ### Replace SNTP Client Configuration Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/01-sntp-client.md Replaces the entire configuration of an existing SntpClient with a new Config object. This method requires a mutable reference to the client. ```rust use rsntp::{Config, SntpClient}; let mut client = SntpClient::new(); let new_config = Config::default(); client.set_config(new_config); ``` -------------------------------- ### (IpAddr, u16) Implementation for ToServerAddrs Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/10-to-server-addrs.md Allows an (IpAddr, u16) tuple to be used with ToServerAddrs. The explicit port in the tuple is always used. ```rust use rsntp::SntpClient; use std::net::IpAddr; let addr: (IpAddr, u16) = ("192.168.1.1".parse().unwrap(), 456); let client = SntpClient::new(); client.synchronize(addr).unwrap(); // Uses port 456 ``` -------------------------------- ### SynchronizationResult Accessors Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/COMPLETION-SUMMARY.txt Shows how to access detailed results after a successful SNTP synchronization. ```rust let offset = result.clock_offset(); let delay = result.round_trip_delay(); let identifier = result.reference_identifier(); let datetime = result.datetime(); let leap = result.leap_indicator(); let stratum = result.stratum(); ``` -------------------------------- ### Set SNTP Bind Address (IPv6) Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/03-config.md Configures the local UDP socket bind address to an IPv6 unspecified address with an auto-selected port. This is necessary for synchronizing with IPv6 servers. ```rust use rsntp::Config; use std::net::Ipv6Addr; // For IPv6 servers let config = Config::default() .bind_address((Ipv6Addr::UNSPECIFIED, 0).into()); ``` -------------------------------- ### clock_offset Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/04-synchronization-result.md Returns the signed offset between the server and local clock. A negative value means the local clock is ahead of the server, and a positive value means it's behind. ```APIDOC ## clock_offset ### Description Returns the signed offset between the server and local clock. A negative value means the local clock is ahead of the server, and a positive value means it's behind. ### Returns `SntpDuration` representing clock difference in seconds ### Example ```rust use rsntp::SntpClient; let client = SntpClient::new(); let result = client.synchronize("pool.ntp.org").unwrap(); let offset = result.clock_offset().as_secs_f64(); if offset > 0.0 { println!("Local clock is {} seconds behind", offset); } else { println!("Local clock is {} seconds ahead", -offset); } ``` ``` -------------------------------- ### Set SNTP Bind Address (IPv4) Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/03-config.md Configures the local UDP socket bind address to a specific IPv4 address with an auto-selected port. Ensure the address string is correctly parsed. ```rust use rsntp::Config; // For specific IPv4 address let config = Config::default() .bind_address("192.168.1.100:0".parse().unwrap()); ``` -------------------------------- ### Signed Duration Wrapper Source: https://github.com/dobaksz/rsntp/blob/master/_autodocs/README.md Details the `SntpDuration` wrapper, used for representing signed time differences and network latencies. ```APIDOC ## SntpDuration ### Description The `SntpDuration` type is a wrapper for signed durations, commonly used to represent clock offsets and round-trip delays in SNTP. ### Methods - **`as_secs_f64()`** - Description: Returns the duration as a floating-point number of seconds. This value can be negative. - **`signum()` → `i32`** - Description: Returns the sign of the duration: 1 for positive, -1 for negative, and 0 for zero. - **`abs_as_std_duration()` → `std::time::Duration`** - Description: Returns the absolute value of the duration as a `std::time::Duration`. - **`into_chrono_duration()` → `chrono::Duration`** - Description: Converts the `SntpDuration` into a `chrono::Duration` object. Requires the `chrono` feature. - **`into_time_duration()` → `time::Duration`** - Description: Converts the `SntpDuration` into a `time::Duration` object. Requires the `time` feature. ```