lobe-core 0.1.1

Local HTTP performance profiling engine — the shared library behind the Lobe CLI. Captures DNS/TCP/TLS/TTFB/download phases per request with grounded network baselines.
Documentation
use crate::models::TimingReport;

#[derive(Debug, Clone, Copy, Default)]
pub struct TimingPhases {
    pub dns_ms: u64,
    pub tcp_ms: u64,
    pub tls_ms: u64,
    pub ttfb_ms: u64,
    pub download_ms: u64,
}

pub fn build_report(
    dns_ms: u64,
    tcp_ms: u64,
    tls_ms: u64,
    ttfb_ms: u64,
    download_ms: u64,
) -> TimingReport {
    let total_ms = calculate_total_ms(dns_ms, tcp_ms, tls_ms, ttfb_ms, download_ms);

    TimingReport {
        dns_ms,
        tcp_ms,
        tls_ms,
        ttfb_ms,
        download_ms,
        total_ms,
    }
}

pub fn build_report_from_phases(phases: TimingPhases) -> TimingReport {
    build_report(
        phases.dns_ms,
        phases.tcp_ms,
        phases.tls_ms,
        phases.ttfb_ms,
        phases.download_ms,
    )
}

pub fn calculate_total_ms(
    dns_ms: u64,
    tcp_ms: u64,
    tls_ms: u64,
    ttfb_ms: u64,
    download_ms: u64,
) -> u64 {
    dns_ms + tcp_ms + tls_ms + ttfb_ms + download_ms
}

#[cfg(test)]
mod tests {
    use super::{build_report, build_report_from_phases, calculate_total_ms, TimingPhases};

    #[test]
    fn calculate_total_ms_sums_all_phases() {
        let total_ms = calculate_total_ms(10, 20, 30, 40, 50);

        assert_eq!(total_ms, 150);
    }

    #[test]
    fn calculate_total_ms_handles_zero_values() {
        let total_ms = calculate_total_ms(0, 0, 0, 0, 0);

        assert_eq!(total_ms, 0);
    }

    #[test]
    fn build_report_populates_each_field() {
        let report = build_report(15, 25, 35, 45, 55);

        assert_eq!(report.dns_ms, 15);
        assert_eq!(report.tcp_ms, 25);
        assert_eq!(report.tls_ms, 35);
        assert_eq!(report.ttfb_ms, 45);
        assert_eq!(report.download_ms, 55);
        assert_eq!(report.total_ms, 175);
    }

    #[test]
    fn build_report_from_phases_uses_phase_values() {
        let phases = TimingPhases {
            dns_ms: 5,
            tcp_ms: 10,
            tls_ms: 15,
            ttfb_ms: 20,
            download_ms: 25,
        };

        let report = build_report_from_phases(phases);

        assert_eq!(report.dns_ms, 5);
        assert_eq!(report.tcp_ms, 10);
        assert_eq!(report.tls_ms, 15);
        assert_eq!(report.ttfb_ms, 20);
        assert_eq!(report.download_ms, 25);
        assert_eq!(report.total_ms, 75);
    }
}