Skip to content

Commit

Permalink
Apply feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
zbraniecki committed Oct 1, 2020
1 parent 1dadc4f commit 31079e4
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 84 deletions.
7 changes: 6 additions & 1 deletion components/datetime/benches/fixtures/tests/patterns.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@
"E, dd/MM",
"LLL",
"E, d MMM y",
"E, dd/MM/y"
"E, dd/MM/y",
"y年M月d日",
"y年M月d日EEEE",
"d בMMM y",
"H นาฬิกา mm นาที ss วินาที zzzz",
"H時mm分ss秒 zzzz"
]
39 changes: 39 additions & 0 deletions components/datetime/src/fields/length.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::convert::TryFrom;

#[derive(Debug)]
pub enum LengthError {
TooLong,
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FieldLength {
One = 1,
TwoDigit = 2,
Abbreviated = 3,
Wide = 4,
Narrow = 5,
Six = 6,
}

macro_rules! try_field_length {
($i:ty) => {
impl TryFrom<$i> for FieldLength {
type Error = LengthError;

fn try_from(input: $i) -> Result<Self, Self::Error> {
Ok(match input {
1 => Self::One,
2 => Self::TwoDigit,
3 => Self::Abbreviated,
4 => Self::Wide,
5 => Self::Narrow,
6 => Self::Six,
_ => return Err(LengthError::TooLong),
})
}
}
};
}

try_field_length!(u8);
try_field_length!(usize);
43 changes: 43 additions & 0 deletions components/datetime/src/fields/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
mod length;
mod symbols;

pub use length::FieldLength;
pub use symbols::*;

use std::convert::{TryFrom, TryInto};

#[derive(Debug)]
pub enum Error {
TooLong(FieldSymbol),
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Field {
pub symbol: FieldSymbol,
pub length: FieldLength,
}

impl Field {}

impl From<(FieldSymbol, FieldLength)> for Field {
fn from(input: (FieldSymbol, FieldLength)) -> Self {
Field {
symbol: input.0,
length: input.1,
}
}
}

impl TryFrom<(FieldSymbol, usize)> for Field {
type Error = Error;
fn try_from(input: (FieldSymbol, usize)) -> Result<Self, Self::Error> {
let (symbol, length) = (
input.0,
input
.1
.try_into()
.map_err(|_| Self::Error::TooLong(input.0))?,
);
Ok(Field { symbol, length })
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
use std::convert::TryFrom;

#[derive(Debug)]
pub enum Error {
Unknown,
TooLong,
pub enum SymbolError {
Unknown(u8),
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FieldLength {
One = 1,
TwoDigit = 2,
Abbreviated = 3,
Wide = 4,
Narrow = 5,
Six = 6,
}

macro_rules! try_field_length {
($i:ty) => {
impl TryFrom<$i> for FieldLength {
type Error = Error;

fn try_from(input: $i) -> Result<Self, Self::Error> {
Ok(match input {
1 => Self::One,
2 => Self::TwoDigit,
3 => Self::Abbreviated,
4 => Self::Wide,
5 => Self::Narrow,
6 => Self::Six,
_ => return Err(Error::TooLong),
})
}
}
};
}

try_field_length!(u8);
try_field_length!(usize);

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FieldSymbol {
Year(Year),
Expand All @@ -52,7 +18,7 @@ pub enum FieldSymbol {
}

impl TryFrom<u8> for FieldSymbol {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'm' => Ok(Self::Minute),
Expand All @@ -75,12 +41,12 @@ pub enum Year {
}

impl TryFrom<u8> for Year {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'y' => Ok(Self::Calendar),
b'Y' => Ok(Self::WeekOf),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -98,12 +64,12 @@ pub enum Month {
}

impl TryFrom<u8> for Month {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'M' => Ok(Self::Format),
b'L' => Ok(Self::StandAlone),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -123,14 +89,14 @@ pub enum Day {
}

impl TryFrom<u8> for Day {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'd' => Ok(Self::DayOfMonth),
b'D' => Ok(Self::DayOfYear),
b'F' => Ok(Self::DayOfWeekInMonth),
b'g' => Ok(Self::ModifiedJulianDay),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -150,14 +116,14 @@ pub enum Hour {
}

impl TryFrom<u8> for Hour {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'K' => Ok(Self::H11),
b'h' => Ok(Self::H12),
b'H' => Ok(Self::H23),
b'k' => Ok(Self::H24),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -176,13 +142,13 @@ pub enum Second {
}

impl TryFrom<u8> for Second {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b's' => Ok(Self::Second),
b'S' => Ok(Self::FractionalSecond),
b'A' => Ok(Self::Millisecond),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -201,13 +167,13 @@ pub enum Weekday {
}

impl TryFrom<u8> for Weekday {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'E' => Ok(Self::Format),
b'e' => Ok(Self::Local),
b'c' => Ok(Self::StandAlone),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -224,11 +190,11 @@ pub enum DayPeriod {
}

impl TryFrom<u8> for DayPeriod {
type Error = Error;
type Error = SymbolError;
fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
b'a' => Ok(Self::AmPm),
_ => Err(Error::Unknown),
b => Err(SymbolError::Unknown(b)),
}
}
}
Expand All @@ -238,20 +204,3 @@ impl From<DayPeriod> for FieldSymbol {
FieldSymbol::DayPeriod(input)
}
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Field {
pub symbol: FieldSymbol,
pub length: FieldLength,
}

impl Field {}

impl From<(FieldSymbol, FieldLength)> for Field {
fn from(input: (FieldSymbol, FieldLength)) -> Self {
Field {
symbol: input.0,
length: input.1,
}
}
}
5 changes: 2 additions & 3 deletions components/datetime/src/pattern/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ use crate::fields;
#[derive(Debug)]
pub enum Error {
Unknown,
FieldTooLong,
FieldTooLong(fields::FieldSymbol),
UnknownSubstitution(u8),
}

impl From<fields::Error> for Error {
fn from(input: fields::Error) -> Self {
match input {
fields::Error::Unknown => Self::Unknown,
fields::Error::TooLong => Self::FieldTooLong,
fields::Error::TooLong(symbol) => Self::FieldTooLong(symbol),
}
}
}
14 changes: 14 additions & 0 deletions components/datetime/src/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,19 @@ mod tests {
.into_iter()
.collect()
);

assert_eq!(
Pattern::from_bytes("y年M月d日").expect("Parsing pattern failed."),
vec![
(fields::Year::Calendar.into(), FieldLength::One).into(),
"年".into(),
(fields::Month::Format.into(), FieldLength::One).into(),
"月".into(),
(fields::Day::DayOfMonth.into(), FieldLength::One).into(),
"日".into(),
]
.into_iter()
.collect()
);
}
}
21 changes: 9 additions & 12 deletions components/datetime/src/pattern/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::error::Error;
use super::{Pattern, PatternItem};
use crate::fields::{Field, FieldLength, FieldSymbol};
use std::convert::TryFrom;
use crate::fields::{Field, FieldSymbol};
use std::convert::{TryFrom, TryInto};

enum Segment {
Symbol { symbol: FieldSymbol, byte: u8 },
Expand Down Expand Up @@ -33,23 +33,21 @@ impl<'p> Parser<'p> {

fn collect_item(&mut self, idx: usize) -> Result<(), Error> {
match self.state.segment {
Segment::Symbol { symbol, .. } => {
self.collect_symbol(symbol, idx)?
}
Segment::Symbol { symbol, .. } => self.collect_symbol(symbol, idx)?,
Segment::Literal => self.collect_literal(idx),
}
Ok(())
}

fn collect_symbol(&mut self, symbol: FieldSymbol, idx: usize) -> Result<(), Error> {
let length = FieldLength::try_from(idx - self.state.start_idx)?;
self.items.push(Field { symbol, length }.into());
let field: Field = (symbol, idx - self.state.start_idx).try_into()?;
self.items.push(field.into());
Ok(())
}

fn collect_literal(&mut self, idx: usize) {
let slice = &self.source[self.state.start_idx..idx];
if !slice.is_empty() {
if idx > self.state.start_idx {
let slice = &self.source[self.state.start_idx..idx];
let item = PatternItem::Literal(slice.to_string());
self.items.push(item);
}
Expand All @@ -69,8 +67,7 @@ impl<'p> Parser<'p> {
segment: Segment::Symbol { symbol, byte: b },
start_idx: idx,
};
} else if let Segment::Symbol { symbol, .. } = self.state.segment
{
} else if let Segment::Symbol { symbol, .. } = self.state.segment {
self.collect_symbol(symbol, idx)?;
self.state = State {
segment: Segment::Literal,
Expand Down Expand Up @@ -100,7 +97,7 @@ impl<'p> Parser<'p> {
bytes.next().ok_or(Error::Unknown)?;
self.state = State {
segment: Segment::Literal,
start_idx: idx + 3
start_idx: idx + 3,
};
}
}
Expand Down

0 comments on commit 31079e4

Please sign in to comment.