kobo-db-tools 0.0.13

A Rust library to parse and analyze Kobo e-reader SQLite databases.
Documentation
use crate::Statistics;
use crate::{ReadingMetric, ReadingSessions};
use std::cmp::Ordering;

impl Statistics for ReadingSessions {
    type Metric = ReadingMetric;

    fn avg(&self) -> f64 {
        let valid_sessions_seconds: Vec<f64> = self
            .valid_sessions()
            .filter_map(|s| s.seconds_read.map(|sec| sec as f64))
            .collect();

        if valid_sessions_seconds.is_empty() {
            0.0
        } else {
            valid_sessions_seconds.iter().sum::<f64>() / valid_sessions_seconds.len() as f64
        }
    }
    fn calculate_percentile(&self, metric: ReadingMetric, percentiles: &[f64]) -> Vec<f64> {
        let mut values: Vec<f64> = self
            .valid_sessions()
            .map(|s| match metric {
                ReadingMetric::SecondsRead => s.seconds_read.unwrap_or(0) as f64,
                ReadingMetric::PagesTurned => s.pages_turned.unwrap_or(0) as f64,
                ReadingMetric::ButtonPressCount => s.button_press_count.unwrap_or(0) as f64,
                ReadingMetric::Progress => (s.end_progress.unwrap_or(0) - s.start_progress) as f64,
            })
            .collect();

        if values.is_empty() {
            return vec![0.0];
        }

        values.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Less));
        percentiles
            .iter()
            .map(|&p| {
                let idx = ((p.clamp(0.0, 1.0)) * ((values.len() - 1) as f64)).round() as usize;
                values.get(idx).copied().unwrap_or(0.0)
            })
            .collect()
    }
}