Skip to main content

YearConfig

Struct YearConfig 

Source
pub struct YearConfig {
    pub min: i32,
    pub max: i32,
    pub expected: IsExpected,
    pub default: Option<i32>,
    pub two_digit_expansion: TwoDigitYearExpansion,
    pub single_digit_year_expansion: bool,
}
Expand description

Configuration for year extraction.

Fields§

§min: i32

Minimum valid year value (inclusive). Default: 0.

§max: i32

Maximum valid year value (inclusive). Default: 3000.

§expected: IsExpected

Whether a year component is expected in the input.

§default: Option<i32>

Default year value to use when the year is not found, if any.

§two_digit_expansion: TwoDigitYearExpansion

Strategy for expanding two-digit years. Default: TwoDigitYearExpansion::SlidingWindow.

§single_digit_year_expansion: bool

When true, a single-digit token (19) is treated as a two-digit year by prepending a zero — 5 becomes 05 — and then expanded according to YearConfig::two_digit_expansion.

This option only applies when the other date components (day and month) have already been filled by unambiguous tokens, so the interpreter can confirm that the single digit is genuinely intended as a year.

Default: false. Enable when processing inputs like "1 January 5" where 5 means year AD 5 (literal) or year 2005 (sliding window).

Implementations§

Source§

impl YearConfig

Source

pub fn try_as_year_candidate(&self, value: i16, digit_count: u8) -> Option<i32>

Return the expanded year value when value (with digit_count original digits) is a plausible year for this config, or None when it is not.

  • 4-digit values are used as-is.
  • 3-digit values (100–999) are treated as literal years.
  • 2-digit values are expanded according to TwoDigitYearExpansion.
  • 1-digit values are accepted only when YearConfig::single_digit_year_expansion is true, in which case value is treated as 0value (e.g. 505) and then expanded using the same two-digit expansion strategy.
  • All other digit counts return None.

The expanded value must also fall within the configured min/max bounds.

Source§

impl YearConfig

Source

pub fn with_range(self, min: i32, max: i32) -> Self

Set the valid year range.

§Panics

Panics if min > max. Use YearConfig::try_with_range when the values come from dynamic input and you need to handle the error.

use partial_date::models::YearConfig;

let config = YearConfig::default().with_range(1760, 1840);
Examples found in repository?
examples/console_entry_config.rs (line 91)
75    pub fn get_config(&self) -> Config {
76        match self {
77            // Strictly day-first numeric dates with all three components
78            // required. Letter-O substitution is disabled since this scenario
79            // expects clean numeric input only.
80            PreDefinedConfigs::StrictDMY => Config::default()
81                .with_day(
82                    DayConfig::default()
83                        .with_expected(IsExpected::Yes),
84                )
85                .with_month(
86                    MonthConfig::default()
87                        .with_expected(IsExpected::Yes)
88                )
89                .with_year(
90                    YearConfig::default()
91                        .with_range(1, 3000)
92                        .with_expected(IsExpected::Yes)
93                        .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
94                )
95                .with_component_order(
96                    ComponentOrder::new(
97                        DateComponent::Day,
98                        DateComponent::Month,
99                        DateComponent::Year,
100                    )
101                    .unwrap(),
102                )
103                .with_letter_o_substitution(false),
104
105            // Wide ranging historical dates that cannot use 2-digit year
106            // expansion as there is no way to know which centuries the dates
107            // will be from. Minimal assumptions about the data when there is
108            // a lot of uncertainty.
109            PreDefinedConfigs::AllHistoricalDates => Config::default().with_year(
110                YearConfig::default()
111                    .with_range(1, 3000)
112                    .with_expected(IsExpected::Yes)
113                    .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
114            ),
115
116            // Constrains the year range to the Industrial Revolution period and
117            // uses a sliding window for 2-digit years centred on 1800.
118            // Component order matches Great Britain's common DD/MM/YYYY format.
119            PreDefinedConfigs::IndustrialRevolutionDates => Config::default()
120                .with_year(
121                    YearConfig::default()
122                        .with_range(1760, 1840)
123                        .with_expected(IsExpected::Yes)
124                        .with_two_digit_expansion(TwoDigitYearExpansion::SlidingWindow {
125                            earliest_year: 1750,
126                            pivot: SlidingWindowPivot::new(50),
127                        }),
128                )
129                .with_component_order(
130                    ComponentOrder::new(
131                        DateComponent::Day,
132                        DateComponent::Month,
133                        DateComponent::Year,
134                    )
135                    .unwrap(),
136                ),
137
138            // Children under 18 — birth years must be in the 2000s and not in
139            // the future. Always(Century(2000)) maps all 2-digit values to the
140            // 2000s; the max of 2026 rejects future years.
141            PreDefinedConfigs::ChildrenBirthdays => Config::default().with_year(
142                YearConfig::default()
143                    .with_range(2000, 2026)
144                    .with_expected(IsExpected::Yes)
145                    .with_two_digit_expansion(TwoDigitYearExpansion::Always(Century::new(2000)))
146                    .with_single_digit_expansion(true),
147            ),
148        }
149    }
Source

pub fn try_with_range( self, min: i32, max: i32, ) -> Result<Self, ConfigRangeError>

Set the valid year range, returning Err if min > max.

Use this when the range values come from dynamic input. For known-valid static values, prefer YearConfig::with_range.

Source

pub fn with_expected(self, expected: IsExpected) -> Self

Set whether a year component is expected in the input.

use partial_date::models::{IsExpected, YearConfig};

let config = YearConfig::default().with_expected(IsExpected::Yes);
Examples found in repository?
examples/console_entry_config.rs (line 92)
75    pub fn get_config(&self) -> Config {
76        match self {
77            // Strictly day-first numeric dates with all three components
78            // required. Letter-O substitution is disabled since this scenario
79            // expects clean numeric input only.
80            PreDefinedConfigs::StrictDMY => Config::default()
81                .with_day(
82                    DayConfig::default()
83                        .with_expected(IsExpected::Yes),
84                )
85                .with_month(
86                    MonthConfig::default()
87                        .with_expected(IsExpected::Yes)
88                )
89                .with_year(
90                    YearConfig::default()
91                        .with_range(1, 3000)
92                        .with_expected(IsExpected::Yes)
93                        .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
94                )
95                .with_component_order(
96                    ComponentOrder::new(
97                        DateComponent::Day,
98                        DateComponent::Month,
99                        DateComponent::Year,
100                    )
101                    .unwrap(),
102                )
103                .with_letter_o_substitution(false),
104
105            // Wide ranging historical dates that cannot use 2-digit year
106            // expansion as there is no way to know which centuries the dates
107            // will be from. Minimal assumptions about the data when there is
108            // a lot of uncertainty.
109            PreDefinedConfigs::AllHistoricalDates => Config::default().with_year(
110                YearConfig::default()
111                    .with_range(1, 3000)
112                    .with_expected(IsExpected::Yes)
113                    .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
114            ),
115
116            // Constrains the year range to the Industrial Revolution period and
117            // uses a sliding window for 2-digit years centred on 1800.
118            // Component order matches Great Britain's common DD/MM/YYYY format.
119            PreDefinedConfigs::IndustrialRevolutionDates => Config::default()
120                .with_year(
121                    YearConfig::default()
122                        .with_range(1760, 1840)
123                        .with_expected(IsExpected::Yes)
124                        .with_two_digit_expansion(TwoDigitYearExpansion::SlidingWindow {
125                            earliest_year: 1750,
126                            pivot: SlidingWindowPivot::new(50),
127                        }),
128                )
129                .with_component_order(
130                    ComponentOrder::new(
131                        DateComponent::Day,
132                        DateComponent::Month,
133                        DateComponent::Year,
134                    )
135                    .unwrap(),
136                ),
137
138            // Children under 18 — birth years must be in the 2000s and not in
139            // the future. Always(Century(2000)) maps all 2-digit values to the
140            // 2000s; the max of 2026 rejects future years.
141            PreDefinedConfigs::ChildrenBirthdays => Config::default().with_year(
142                YearConfig::default()
143                    .with_range(2000, 2026)
144                    .with_expected(IsExpected::Yes)
145                    .with_two_digit_expansion(TwoDigitYearExpansion::Always(Century::new(2000)))
146                    .with_single_digit_expansion(true),
147            ),
148        }
149    }
Source

pub fn with_default(self, default: i32) -> Self

Set the default year value to use when no year is found in the input.

use partial_date::models::YearConfig;

let config = YearConfig::default().with_default(2025);
Source

pub fn with_two_digit_expansion( self, two_digit_expansion: TwoDigitYearExpansion, ) -> Self

Set the two-digit year expansion strategy.

use partial_date::models::{
    Century, SlidingWindowPivot, TwoDigitYearExpansion, YearConfig,
};

// All two-digit years map to the 2000s.
let config = YearConfig::default()
    .with_two_digit_expansion(TwoDigitYearExpansion::Always(Century::new(2000)));

// Industrial Revolution era window.
let config = YearConfig::default()
    .with_range(1760, 1840)
    .with_two_digit_expansion(TwoDigitYearExpansion::SlidingWindow {
        earliest_year: 1750,
        pivot: SlidingWindowPivot::new(50),
    });
Examples found in repository?
examples/console_entry_config.rs (line 93)
75    pub fn get_config(&self) -> Config {
76        match self {
77            // Strictly day-first numeric dates with all three components
78            // required. Letter-O substitution is disabled since this scenario
79            // expects clean numeric input only.
80            PreDefinedConfigs::StrictDMY => Config::default()
81                .with_day(
82                    DayConfig::default()
83                        .with_expected(IsExpected::Yes),
84                )
85                .with_month(
86                    MonthConfig::default()
87                        .with_expected(IsExpected::Yes)
88                )
89                .with_year(
90                    YearConfig::default()
91                        .with_range(1, 3000)
92                        .with_expected(IsExpected::Yes)
93                        .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
94                )
95                .with_component_order(
96                    ComponentOrder::new(
97                        DateComponent::Day,
98                        DateComponent::Month,
99                        DateComponent::Year,
100                    )
101                    .unwrap(),
102                )
103                .with_letter_o_substitution(false),
104
105            // Wide ranging historical dates that cannot use 2-digit year
106            // expansion as there is no way to know which centuries the dates
107            // will be from. Minimal assumptions about the data when there is
108            // a lot of uncertainty.
109            PreDefinedConfigs::AllHistoricalDates => Config::default().with_year(
110                YearConfig::default()
111                    .with_range(1, 3000)
112                    .with_expected(IsExpected::Yes)
113                    .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
114            ),
115
116            // Constrains the year range to the Industrial Revolution period and
117            // uses a sliding window for 2-digit years centred on 1800.
118            // Component order matches Great Britain's common DD/MM/YYYY format.
119            PreDefinedConfigs::IndustrialRevolutionDates => Config::default()
120                .with_year(
121                    YearConfig::default()
122                        .with_range(1760, 1840)
123                        .with_expected(IsExpected::Yes)
124                        .with_two_digit_expansion(TwoDigitYearExpansion::SlidingWindow {
125                            earliest_year: 1750,
126                            pivot: SlidingWindowPivot::new(50),
127                        }),
128                )
129                .with_component_order(
130                    ComponentOrder::new(
131                        DateComponent::Day,
132                        DateComponent::Month,
133                        DateComponent::Year,
134                    )
135                    .unwrap(),
136                ),
137
138            // Children under 18 — birth years must be in the 2000s and not in
139            // the future. Always(Century(2000)) maps all 2-digit values to the
140            // 2000s; the max of 2026 rejects future years.
141            PreDefinedConfigs::ChildrenBirthdays => Config::default().with_year(
142                YearConfig::default()
143                    .with_range(2000, 2026)
144                    .with_expected(IsExpected::Yes)
145                    .with_two_digit_expansion(TwoDigitYearExpansion::Always(Century::new(2000)))
146                    .with_single_digit_expansion(true),
147            ),
148        }
149    }
Source

pub fn with_single_digit_expansion(self, enabled: bool) -> Self

Set whether single-digit tokens are expanded as two-digit years.

When true, a single-digit token (e.g. 5) is treated as 05 and then expanded according to the configured YearConfig::two_digit_expansion strategy.

use partial_date::models::YearConfig;

let config = YearConfig::default().with_single_digit_expansion(true);
Examples found in repository?
examples/console_entry_config.rs (line 146)
75    pub fn get_config(&self) -> Config {
76        match self {
77            // Strictly day-first numeric dates with all three components
78            // required. Letter-O substitution is disabled since this scenario
79            // expects clean numeric input only.
80            PreDefinedConfigs::StrictDMY => Config::default()
81                .with_day(
82                    DayConfig::default()
83                        .with_expected(IsExpected::Yes),
84                )
85                .with_month(
86                    MonthConfig::default()
87                        .with_expected(IsExpected::Yes)
88                )
89                .with_year(
90                    YearConfig::default()
91                        .with_range(1, 3000)
92                        .with_expected(IsExpected::Yes)
93                        .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
94                )
95                .with_component_order(
96                    ComponentOrder::new(
97                        DateComponent::Day,
98                        DateComponent::Month,
99                        DateComponent::Year,
100                    )
101                    .unwrap(),
102                )
103                .with_letter_o_substitution(false),
104
105            // Wide ranging historical dates that cannot use 2-digit year
106            // expansion as there is no way to know which centuries the dates
107            // will be from. Minimal assumptions about the data when there is
108            // a lot of uncertainty.
109            PreDefinedConfigs::AllHistoricalDates => Config::default().with_year(
110                YearConfig::default()
111                    .with_range(1, 3000)
112                    .with_expected(IsExpected::Yes)
113                    .with_two_digit_expansion(TwoDigitYearExpansion::Literal),
114            ),
115
116            // Constrains the year range to the Industrial Revolution period and
117            // uses a sliding window for 2-digit years centred on 1800.
118            // Component order matches Great Britain's common DD/MM/YYYY format.
119            PreDefinedConfigs::IndustrialRevolutionDates => Config::default()
120                .with_year(
121                    YearConfig::default()
122                        .with_range(1760, 1840)
123                        .with_expected(IsExpected::Yes)
124                        .with_two_digit_expansion(TwoDigitYearExpansion::SlidingWindow {
125                            earliest_year: 1750,
126                            pivot: SlidingWindowPivot::new(50),
127                        }),
128                )
129                .with_component_order(
130                    ComponentOrder::new(
131                        DateComponent::Day,
132                        DateComponent::Month,
133                        DateComponent::Year,
134                    )
135                    .unwrap(),
136                ),
137
138            // Children under 18 — birth years must be in the 2000s and not in
139            // the future. Always(Century(2000)) maps all 2-digit values to the
140            // 2000s; the max of 2026 rejects future years.
141            PreDefinedConfigs::ChildrenBirthdays => Config::default().with_year(
142                YearConfig::default()
143                    .with_range(2000, 2026)
144                    .with_expected(IsExpected::Yes)
145                    .with_two_digit_expansion(TwoDigitYearExpansion::Always(Century::new(2000)))
146                    .with_single_digit_expansion(true),
147            ),
148        }
149    }

Trait Implementations§

Source§

impl Clone for YearConfig

Source§

fn clone(&self) -> YearConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for YearConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for YearConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.