Skip to main content

whichtime_sys/
context.rs

1//! Parsing context
2
3use crate::components::FastComponents;
4use crate::dictionaries::Locale;
5use crate::results::{ParsedResult, ReferenceWithTimezone};
6use crate::scanner::TokenScanner;
7
8/// Shared state for a single parse request.
9///
10/// Parsers and refiners receive a `ParsingContext` so they can reuse the input
11/// text, reference time, locale, and precomputed token scan.
12pub struct ParsingContext<'a> {
13    /// Original input text.
14    pub text: &'a str,
15    /// Lowercased input cached for parser prefilters.
16    lower_text: String,
17    /// Reference date/time used to resolve relative expressions.
18    pub reference: &'a ReferenceWithTimezone,
19    /// Tokens discovered during the scanner pre-pass.
20    pub tokens: Vec<crate::scanner::Token>,
21    /// Active locale for the parse request.
22    pub locale: Locale,
23}
24
25impl<'a> ParsingContext<'a> {
26    /// Create a new English parsing context.
27    pub fn new(text: &'a str, reference: &'a ReferenceWithTimezone) -> Self {
28        Self::with_locale(text, reference, Locale::En)
29    }
30
31    /// Create a parsing context for a specific locale.
32    pub fn with_locale(
33        text: &'a str,
34        reference: &'a ReferenceWithTimezone,
35        locale: Locale,
36    ) -> Self {
37        let lower_text = text.to_lowercase();
38        let tokens = TokenScanner::scan_locale(&lower_text, locale);
39
40        Self {
41            text,
42            lower_text,
43            reference,
44            tokens,
45            locale,
46        }
47    }
48
49    /// Return the cached lowercase representation of the input.
50    #[inline]
51    pub fn lower_text(&self) -> &str {
52        &self.lower_text
53    }
54
55    /// Create a fresh component set seeded from the reference date.
56    #[inline]
57    pub fn create_components(&self) -> FastComponents {
58        FastComponents::with_defaults(self.reference)
59    }
60
61    /// Build a [`ParsedResult`] for a matched span.
62    pub fn create_result(
63        &self,
64        index: usize,
65        end_index: usize,
66        start: FastComponents,
67        end: Option<FastComponents>,
68    ) -> ParsedResult {
69        let text = &self.text[index..end_index];
70        ParsedResult::new(self.reference, index, text, start, end)
71    }
72
73    /// Return `true` when the scanner found a token of the given type.
74    pub fn has_token_type(&self, token_type: crate::scanner::TokenType) -> bool {
75        self.tokens.iter().any(|t| t.token_type == token_type)
76    }
77}