use crate::calculation::duration::reverse_duration;
use crate::common::abstract_refiners::{Merging, MergingRefiner};
use crate::core::chrono::Refiner;
use crate::core::components::{Component, ParsingComponents};
use crate::core::configuration::Flags;
use crate::core::context::ParsingContext;
use crate::core::reference::ReferenceWithTimezone;
use crate::core::result::ParsingResult;
use crate::js_regex;
use crate::locales::it::constants::parse_duration;
pub const UPSTREAM: &str = "ITMergeRelativeFollowByDateRefiner";
pub fn create(_flags: &Flags) -> Box<dyn Refiner> {
Box::new(Merging::new(ItMergeRelativeFollowByDateRefiner))
}
fn has_implied_earlier_reference_date(result: &ParsingResult) -> bool {
js_regex!(r"\s+(prima|da)$", "i").is_match(&result.text)
}
fn has_implied_later_reference_date(result: &ParsingResult) -> bool {
js_regex!(r"\s+(dopo|dal?)$", "i").is_match(&result.text)
}
struct ItMergeRelativeFollowByDateRefiner;
impl MergingRefiner for ItMergeRelativeFollowByDateRefiner {
fn should_merge_results(
&self,
text_between: &str,
current: &ParsingResult,
next: &ParsingResult,
_context: &ParsingContext,
) -> bool {
if !js_regex!(r"^\s*$", "i").is_match(text_between) {
return false;
}
if !has_implied_earlier_reference_date(current) && !has_implied_later_reference_date(current) {
return false;
}
let truthy = |c| next.start.get(c).is_some_and(|v| v != 0);
truthy(Component::Day) && truthy(Component::Month) && truthy(Component::Year)
}
fn merge_results(
&self,
text_between: &str,
current: ParsingResult,
next: ParsingResult,
_context: &ParsingContext,
) -> ParsingResult {
let mut duration = parse_duration(¤t.text).unwrap_or_default();
if has_implied_earlier_reference_date(¤t) {
duration = reverse_duration(&duration);
}
let components = ParsingComponents::create_relative_from_reference(
ReferenceWithTimezone::new(next.start.date(), None),
&mut duration,
);
ParsingResult::new(
next.reference,
current.index,
format!("{}{}{}", current.text, text_between, next.text),
Some(components),
None,
)
}
}