use std::collections::HashMap;
use chrono::{FixedOffset, NaiveDate, NaiveDateTime, TimeZone};
pub struct RecordParser<'a> {
fields: &'a HashMap<String, String>,
}
impl<'a> RecordParser<'a> {
pub fn new(fields: &'a HashMap<String, String>) -> Self {
Self { fields }
}
pub fn get_string(&self, key: &str) -> Option<String> {
self.fields.get(key).map(|s| s.trim().to_string())
}
pub fn parse_date(&self, key: &str) -> Option<i64> {
self.fields.get(key).and_then(|s| {
NaiveDate::parse_from_str(s, "%Y-%m-%d")
.ok()
.and_then(|d| d.and_hms_opt(0, 0, 0))
.and_then(|dt| {
FixedOffset::east_opt(8 * 3600)
.and_then(|offset| offset.from_local_datetime(&dt).single())
.map(|dt| dt.timestamp())
})
})
}
pub fn parse_datetime(&self, key: &str) -> Option<i64> {
self.fields.get(key).and_then(|s| {
NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S")
.ok()
.and_then(|dt| {
FixedOffset::east_opt(8 * 3600)
.and_then(|offset| offset.from_local_datetime(&dt).single())
.map(|dt| dt.timestamp())
})
})
}
pub fn parse_u32(&self, key: &str) -> Option<u32> {
self.fields.get(key).and_then(|s| s.trim().parse().ok())
}
pub fn parse_f64(&self, key: &str) -> Option<f64> {
self.fields.get(key).and_then(|s| s.trim().parse().ok())
}
pub fn calculate_quality_score(&self) -> f64 {
let total = self.fields.len() as f64;
if total == 0.0 {
return 0.0;
}
let empty_count = self.fields.values().filter(|v| v.trim().is_empty()).count() as f64;
(total - empty_count) / total
}
}