By placing the code for the parse executable inside a module inside the organic library, we only need to expose the entrypoint publicly rather than all functions it calls. This hides the event_count module, but I will be expanding the practice to the rest of the code base shortly. This is important for not inadvertently promising stability w.r.t. semver for essentially internal functions for development tools. It was the parse binary, not compare.
44 lines
1.3 KiB
Rust
44 lines
1.3 KiB
Rust
use std::collections::HashMap;
|
|
use std::sync::Mutex;
|
|
|
|
use super::EventType;
|
|
use crate::parser::OrgSource;
|
|
|
|
#[derive(Debug, Eq, Hash, PartialEq)]
|
|
struct EventKey {
|
|
event_type: EventType,
|
|
byte_offset: usize,
|
|
}
|
|
|
|
pub(crate) type EventCount = usize;
|
|
|
|
static GLOBAL_DATA: Mutex<Option<HashMap<EventKey, EventCount>>> = Mutex::new(None);
|
|
|
|
pub(crate) fn record_event(event_type: EventType, input: OrgSource<'_>) {
|
|
let mut db = GLOBAL_DATA.lock().unwrap();
|
|
let db = db.get_or_insert_with(HashMap::new);
|
|
let key = EventKey {
|
|
event_type,
|
|
byte_offset: input.get_byte_offset(),
|
|
};
|
|
*db.entry(key).or_insert(0) += 1;
|
|
}
|
|
|
|
pub(crate) fn report(original_document: &str) {
|
|
let mut db = GLOBAL_DATA.lock().unwrap();
|
|
let db = db.get_or_insert_with(HashMap::new);
|
|
let mut results: Vec<_> = db.iter().collect();
|
|
results.sort_by_key(|(_k, v)| *v);
|
|
// This would put the most common at the top, but that is a pain when there is already a lot of output from the parser.
|
|
// results.sort_by(|(_ak, av), (_bk, bv)| bv.cmp(av));
|
|
for (key, count) in results {
|
|
println!(
|
|
"{:?} {} character offset: {} byte offset: {}",
|
|
key.event_type,
|
|
count,
|
|
original_document[..key.byte_offset].chars().count() + 1,
|
|
key.byte_offset
|
|
)
|
|
}
|
|
}
|