Skip to main content

pgdrift_core/
stats.rs

1use crate::types::JsonType;
2use serde::Serialize;
3use serde_json::Value;
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Serialize)]
7pub struct FieldStats {
8    pub path: String,
9    pub occurrences: u64,
10    pub total_samples: u64,
11    pub density: f64,
12    pub null_count: u64,
13    pub types: HashMap<JsonType, u64>,
14    pub examples: Vec<Value>,
15    pub depth: usize,
16}
17
18impl FieldStats {
19    pub fn new(path: String, depth: usize) -> Self {
20        Self {
21            path,
22            occurrences: 0,
23            total_samples: 0,
24            density: 0.0,
25            null_count: 0,
26            types: HashMap::new(),
27            examples: Vec::new(),
28            depth,
29        }
30    }
31
32    /// Record and occurence of this field with its value
33    pub fn record(&mut self, value: &Value) {
34        self.occurrences += 1;
35
36        let json_type = JsonType::from_value(value);
37        *self.types.entry(json_type).or_insert(0) += 1;
38
39        if matches!(value, Value::Null) {
40            self.null_count += 1;
41        }
42
43        // store examples  - max 10
44        if self.examples.len() < 10 {
45            self.examples.push(value.clone());
46        }
47    }
48
49    pub fn finalize(&mut self, total_samples: u64) {
50        self.total_samples = total_samples;
51
52        if self.total_samples > 0 {
53            self.density = self.occurrences as f64 / self.total_samples as f64;
54        }
55    }
56}