elefant-client 0.1.0

A pure rust implementation of a postgres client that is independent of the executor runtime
Documentation
use std::collections::HashMap;
use std::sync::{Mutex, OnceLock};
use std::time::Duration;

pub struct Profiler {
    measurements: Mutex<HashMap<&'static str, Measurement>>,
}

#[derive(Debug)]
pub struct Measurement {
    duration: Duration,
    count: u64,
}

static PROFILER: OnceLock<Profiler> = OnceLock::new();

impl Profiler {
    fn get() -> &'static Profiler {
        PROFILER.get_or_init(|| Profiler {
            measurements: Mutex::new(HashMap::new()),
        })
    }

    pub fn start(name: &'static str) -> ProfilerGuard {
        ProfilerGuard {
            name,
            start: std::time::Instant::now(),
        }
    }

    pub fn print_results() {
        let measurements = Profiler::get().measurements.lock().unwrap();

        let mut items = measurements.iter().collect::<Vec<_>>();
        items.sort_by(|a, b| a.1.duration.cmp(&b.1.duration).reverse());

        for (name, duration) in items {
            println!("{name}: {duration:?}");
        }
    }

    pub fn reset() {
        let mut measurements = Profiler::get().measurements.lock().unwrap();
        measurements.clear();
    }
}

pub struct ProfilerGuard {
    name: &'static str,
    start: std::time::Instant,
}

impl Drop for ProfilerGuard {
    fn drop(&mut self) {
        let elapsed = self.start.elapsed();
        let mut measurements = Profiler::get().measurements.lock().unwrap();
        let entry = measurements.entry(self.name);
        match entry {
            std::collections::hash_map::Entry::Occupied(mut entry) => {
                let current = entry.get_mut();
                current.duration += elapsed;
                current.count += 1;
            }
            std::collections::hash_map::Entry::Vacant(entry) => {
                entry.insert(Measurement {
                    duration: elapsed,
                    count: 1,
                });
            }
        }
    }
}