speedtest-tui 0.1.1

A terminal-based network speed test tool with real-time gauges and graphs
use anyhow::Result;
use hickory_resolver::config::{ResolverConfig, ResolverOpts};
use hickory_resolver::TokioAsyncResolver;
use serde::{Deserialize, Serialize};
use std::time::Instant;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DnsResult {
    pub domain: String,
    pub resolution_time_ms: f64,
    pub resolved_ips: Vec<String>,
}

/// Measure DNS resolution time for a domain
pub async fn measure_dns(domain: &str) -> Result<DnsResult> {
    let resolver = TokioAsyncResolver::tokio(ResolverConfig::default(), ResolverOpts::default());

    let start = Instant::now();
    let response = resolver.lookup_ip(domain).await?;
    let elapsed = start.elapsed();

    let resolved_ips: Vec<String> = response.iter().map(|ip| ip.to_string()).collect();

    Ok(DnsResult {
        domain: domain.to_string(),
        resolution_time_ms: elapsed.as_secs_f64() * 1000.0,
        resolved_ips,
    })
}

#[allow(dead_code)]
pub async fn measure_dns_with_server(domain: &str, dns_server: &str) -> Result<DnsResult> {
    use hickory_resolver::config::{NameServerConfig, Protocol};
    use std::net::SocketAddr;

    let socket_addr: SocketAddr = format!("{}:53", dns_server).parse()?;
    let name_server = NameServerConfig::new(socket_addr, Protocol::Udp);

    let mut config = ResolverConfig::new();
    config.add_name_server(name_server);

    let resolver = TokioAsyncResolver::tokio(config, ResolverOpts::default());

    let start = Instant::now();
    let response = resolver.lookup_ip(domain).await?;
    let elapsed = start.elapsed();

    let resolved_ips: Vec<String> = response.iter().map(|ip| ip.to_string()).collect();

    Ok(DnsResult {
        domain: domain.to_string(),
        resolution_time_ms: elapsed.as_secs_f64() * 1000.0,
        resolved_ips,
    })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_dns_lookup() {
        let result = measure_dns("google.com").await;
        assert!(result.is_ok());
        let dns = result.unwrap();
        assert!(dns.resolution_time_ms > 0.0);
        assert!(!dns.resolved_ips.is_empty());
    }
}