docvortex_core/
text_classification.rs1use std::collections::HashSet;
3
4#[derive(Default)]
5pub struct Counts {
6 pub null: usize,
7 pub replacement: usize,
8 pub control: usize,
9 pub private: usize,
10 pub map_error: usize,
11 pub non_generated: usize,
12 pub fonts: Vec<(usize, usize, usize)>,
13 pub font_first: Vec<[usize; 3]>,
14}
15
16pub fn count(
18 records: &[(u32, bool, bool, usize)],
19 font_count: usize,
20 cjk: &[(u32, u32)],
21 allowed: &HashSet<u32>,
22 private: (u32, u32),
23) -> Counts {
24 let mut result = Counts {
25 fonts: vec![(0, 0, 0); font_count],
26 font_first: vec![[usize::MAX; 3]; font_count],
27 ..Counts::default()
28 };
29 for (position, &(code, generated, error, font)) in records.iter().enumerate() {
30 if code == 0 {
31 result.null += 1;
32 } else if code == 0xfffd {
33 result.replacement += 1;
34 } else if (code < 32 || (127..=159).contains(&code)) && !allowed.contains(&code) {
35 result.control += 1;
36 } else if private.0 <= code && code <= private.1 {
37 result.private += 1;
38 }
39 result.map_error += usize::from(error);
40 result.fonts[font].0 += 1;
41 result.font_first[font][0] = result.font_first[font][0].min(position);
42 if !generated {
43 result.non_generated += 1;
44 result.fonts[font].1 += 1;
45 result.font_first[font][1] = result.font_first[font][1].min(position);
46 if cjk.iter().any(|&(start, end)| start <= code && code <= end) {
47 result.fonts[font].2 += 1;
48 result.font_first[font][2] = result.font_first[font][2].min(position);
49 }
50 }
51 }
52 result
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
61 fn raw_priority_and_generated_counts() {
62 let records = [
63 (0, false, false, 0),
64 (0xfffd, true, true, 0),
65 (2, false, false, 0),
66 (65, false, true, 1),
67 (0xffffffff, false, false, 1),
68 ];
69 let result = count(&records, 2, &[(65, 90)], &HashSet::new(), (0, 100));
70 assert_eq!(
71 (
72 result.null,
73 result.replacement,
74 result.control,
75 result.private,
76 result.map_error,
77 result.non_generated
78 ),
79 (1, 1, 1, 1, 2, 4)
80 );
81 assert_eq!(result.fonts, vec![(3, 2, 0), (2, 2, 1)]);
82 }
83}