whichtime_sys/refiners/
merge_datetime.rs1use crate::components::Component;
4use crate::context::ParsingContext;
5use crate::refiners::Refiner;
6use crate::results::ParsedResult;
7
8pub struct MergeDateTimeRefiner;
10
11impl Refiner for MergeDateTimeRefiner {
12 fn refine(&self, context: &ParsingContext, results: Vec<ParsedResult>) -> Vec<ParsedResult> {
13 if results.len() < 2 {
14 return results;
15 }
16
17 let mut merged = Vec::with_capacity(results.len());
18 let mut i = 0;
19
20 while i < results.len() {
21 let current = &results[i];
22
23 if i + 1 < results.len() {
25 let next = &results[i + 1];
26
27 let gap_start = current.end_index;
29 let gap_end = next.index;
30
31 if gap_end >= gap_start {
32 let gap = if gap_end > gap_start {
33 &context.text[gap_start..gap_end]
34 } else {
35 ""
36 };
37 let gap_lower = gap.trim().to_lowercase();
38 let is_connectable = gap_lower.is_empty()
39 || gap_lower == "at"
40 || gap_lower == ","
41 || gap_lower == "on"
42 || gap_lower == "um" || gap_lower == "a" || gap_lower == "à" || gap_lower == "om" || gap_lower == "в" || gap_lower == "に" || gap_lower == "の" || gap_lower == "о"; if is_connectable {
52 let current_is_date = current.start.is_only_date();
54 let current_is_time = current.start.is_only_time();
55 let next_is_date = next.start.is_only_date();
56 let next_is_time = next.start.is_only_time();
57
58 if (current_is_date && next_is_time) || (current_is_time && next_is_date) {
59 let (date_result, time_result) = if current_is_date {
61 (current, next)
62 } else {
63 (next, current)
64 };
65
66 let mut merged_components = date_result.start;
67
68 if let Some(year) = merged_components.get(Component::Year) {
71 merged_components.assign(Component::Year, year);
72 }
73
74 if let Some(hour) = time_result.start.get(Component::Hour) {
76 merged_components.assign(Component::Hour, hour);
77 }
78 if let Some(minute) = time_result.start.get(Component::Minute) {
79 merged_components.assign(Component::Minute, minute);
80 }
81 if let Some(second) = time_result.start.get(Component::Second) {
82 merged_components.assign(Component::Second, second);
83 }
84 if let Some(meridiem) = time_result.start.get(Component::Meridiem) {
85 merged_components.assign(Component::Meridiem, meridiem);
86 }
87
88 let merged_end = if let Some(mut end_comp) = time_result.end {
89 if let Some(year) = date_result.start.get(Component::Year) {
90 end_comp.assign(Component::Year, year);
91 }
92 if let Some(month) = date_result.start.get(Component::Month) {
93 end_comp.assign(Component::Month, month);
94 }
95 if let Some(day) = date_result.start.get(Component::Day) {
96 end_comp.assign(Component::Day, day);
97 }
98 Some(end_comp)
99 } else {
100 date_result.end
101 };
102
103 let merged_result = ParsedResult::new(
104 context.reference,
105 current.index,
106 &context.text[current.index..next.end_index],
107 merged_components,
108 merged_end,
109 );
110
111 merged.push(merged_result);
112 i += 2;
113 continue;
114 }
115 }
116 }
117 }
118
119 merged.push(results[i].clone());
120 i += 1;
121 }
122
123 merged
124 }
125}