Skip to main content

speedtest/
utils.rs

1// File: src\utils.rs
2// Author: Hadi Cahyadi <cumulus13@gmail.com>
3// Date: 2026-02-09
4// Description: 
5// License: MIT
6
7/// Calculate distance between two geographic coordinates using Haversine formula
8pub fn distance(lat1: f64, lon1: f64, lat2: f64, lon2: f64) -> f64 {
9    let radius = 6371.0; // Earth radius in km
10
11    let dlat = (lat2 - lat1).to_radians();
12    let dlon = (lon2 - lon1).to_radians();
13
14    let a = (dlat / 2.0).sin().powi(2)
15        + lat1.to_radians().cos() * lat2.to_radians().cos() * (dlon / 2.0).sin().powi(2);
16
17    let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
18
19    radius * c
20}
21
22/// Build user agent string
23pub fn build_user_agent() -> String {
24    format!(
25        "Mozilla/5.0 ({} {}) speedtest/1.0.0",
26        std::env::consts::OS,
27        std::env::consts::ARCH
28    )
29}
30
31/// Generate cache buster parameter
32pub fn cache_buster() -> String {
33    use std::time::{SystemTime, UNIX_EPOCH};
34    let timestamp = SystemTime::now()
35        .duration_since(UNIX_EPOCH)
36        .unwrap()
37        .as_millis();
38    format!("{}", timestamp)
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn test_distance() {
47        // Test distance between New York and London
48        let d = distance(40.7128, -74.0060, 51.5074, -0.1278);
49        // Should be approximately 5570 km
50        assert!((d - 5570.0).abs() < 50.0);
51    }
52
53    #[test]
54    fn test_user_agent() {
55        let ua = build_user_agent();
56        assert!(ua.contains("Mozilla/5.0"));
57        assert!(ua.contains("speedtest"));
58    }
59
60    #[test]
61    fn test_cache_buster() {
62        let cb1 = cache_buster();
63        std::thread::sleep(std::time::Duration::from_millis(10));
64        let cb2 = cache_buster();
65        assert_ne!(cb1, cb2);
66    }
67}