Skip to content

Commit

Permalink
Components bag support with only skeleton matching (#587)
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatum authored Apr 8, 2021
1 parent 03be3a1 commit 6db4862
Show file tree
Hide file tree
Showing 13 changed files with 1,305 additions and 45 deletions.
3 changes: 3 additions & 0 deletions components/datetime/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use crate::pattern;
use crate::skeleton::SkeletonError;
use icu_provider::prelude::DataError;

/// A list of possible error outcomes for the [`DateTimeFormat`](crate::DateTimeFormat) struct.
Expand All @@ -18,6 +19,8 @@ pub enum DateTimeFormatError {
/// Missing field in date time input
/// TODO: How can we return which field was missing?
MissingInputField,
/// An error from skeleton matching,
Skeleton(SkeletonError),
}

impl From<DataError> for DateTimeFormatError {
Expand Down
15 changes: 15 additions & 0 deletions components/datetime/src/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ pub struct Field {
pub length: FieldLength,
}

impl Field {
pub fn get_length_type(&self) -> TextOrNumeric {
match self.symbol {
FieldSymbol::Year(year) => year.get_length_type(&self.length),
FieldSymbol::Month(month) => month.get_length_type(&self.length),
FieldSymbol::Day(day) => day.get_length_type(&self.length),
FieldSymbol::Weekday(weekday) => weekday.get_length_type(&self.length),
FieldSymbol::DayPeriod(day_period) => day_period.get_length_type(&self.length),
FieldSymbol::Hour(hour) => hour.get_length_type(&self.length),
FieldSymbol::Minute => TextOrNumeric::Numeric,
FieldSymbol::Second(second) => second.get_length_type(&self.length),
}
}
}

impl From<(FieldSymbol, FieldLength)> for Field {
fn from(input: (FieldSymbol, FieldLength)) -> Self {
Self {
Expand Down
68 changes: 68 additions & 0 deletions components/datetime/src/fields/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use crate::fields::FieldLength;
use std::{cmp::Ordering, convert::TryFrom};

#[derive(Debug, PartialEq)]
Expand All @@ -28,6 +29,18 @@ pub enum FieldSymbol {
Second(Second),
}

#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum TextOrNumeric {
Text,
Numeric,
}

/// FieldSymbols can be either text or numeric. This categorization is important when matching
/// skeletons with a components::Bag.
pub trait LengthType {
fn get_length_type(&self, length: &FieldLength) -> TextOrNumeric;
}

impl FieldSymbol {
/// Skeletons are a Vec<Field>, and represent the Fields that can be used to match to a
/// specific pattern. The order of the Vec does not affect the Pattern that is output.
Expand Down Expand Up @@ -158,6 +171,12 @@ pub enum Year {
WeekOf,
}

impl LengthType for Year {
fn get_length_type(&self, _length: &FieldLength) -> TextOrNumeric {
TextOrNumeric::Numeric
}
}

impl TryFrom<u8> for Year {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -185,6 +204,19 @@ pub enum Month {
StandAlone,
}

impl LengthType for Month {
fn get_length_type(&self, length: &FieldLength) -> TextOrNumeric {
match length {
FieldLength::One => TextOrNumeric::Numeric,
FieldLength::TwoDigit => TextOrNumeric::Numeric,
FieldLength::Abbreviated => TextOrNumeric::Text,
FieldLength::Wide => TextOrNumeric::Text,
FieldLength::Narrow => TextOrNumeric::Text,
FieldLength::Six => TextOrNumeric::Text,
}
}
}

impl TryFrom<u8> for Month {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -214,6 +246,12 @@ pub enum Day {
ModifiedJulianDay,
}

impl LengthType for Day {
fn get_length_type(&self, _length: &FieldLength) -> TextOrNumeric {
TextOrNumeric::Numeric
}
}

impl TryFrom<u8> for Day {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -245,6 +283,12 @@ pub enum Hour {
H24,
}

impl LengthType for Hour {
fn get_length_type(&self, _length: &FieldLength) -> TextOrNumeric {
TextOrNumeric::Numeric
}
}

impl TryFrom<u8> for Hour {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -275,6 +319,12 @@ pub enum Second {
Millisecond,
}

impl LengthType for Second {
fn get_length_type(&self, _length: &FieldLength) -> TextOrNumeric {
TextOrNumeric::Numeric
}
}

impl TryFrom<u8> for Second {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -304,6 +354,18 @@ pub enum Weekday {
StandAlone,
}

impl LengthType for Weekday {
fn get_length_type(&self, length: &FieldLength) -> TextOrNumeric {
match self {
Weekday::Format => TextOrNumeric::Text,
Weekday::Local | Weekday::StandAlone => match length {
FieldLength::One | FieldLength::TwoDigit => TextOrNumeric::Text,
_ => TextOrNumeric::Numeric,
},
}
}
}

impl TryFrom<u8> for Weekday {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -332,6 +394,12 @@ pub enum DayPeriod {
NoonMidnight,
}

impl LengthType for DayPeriod {
fn get_length_type(&self, _length: &FieldLength) -> TextOrNumeric {
TextOrNumeric::Text
}
}

impl TryFrom<u8> for DayPeriod {
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
Expand Down
Loading

0 comments on commit 6db4862

Please sign in to comment.