Skip to content

Commit

Permalink
date parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
NYBACHOK committed Nov 1, 2024
1 parent 484c240 commit f8cd5d8
Showing 1 changed file with 119 additions and 0 deletions.
119 changes: 119 additions & 0 deletions process/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ mod time {
mod timespec {
use std::str::FromStr;

use crate::tokens::{DayNumber, DayOfWeek, MonthName, TokenParsingError, YearNumber};

// TODO: Proper errors for each case and token
#[derive(Debug, PartialEq)]
pub struct TimespecParsingError;
Expand All @@ -356,6 +358,12 @@ mod timespec {
}
}

impl From<TokenParsingError> for TimespecParsingError {
fn from(_value: TokenParsingError) -> Self {
Self
}
}

pub enum IncPeriod {
Minute,
Minutes,
Expand Down Expand Up @@ -431,6 +439,81 @@ mod timespec {
Ok(result)
}
}

pub enum Date {
MontDay {
month_name: MonthName,
day_number: DayNumber,
},
MontDayYear {
month_name: MonthName,
day_number: DayNumber,
year_number: YearNumber,
},
DayOfWeek(DayOfWeek),
Today,
Tomorrow,
}

impl FromStr for Date {
type Err = TimespecParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let result = match s {
"today" => Self::Today,
"tomorrow" => Self::Tomorrow,
_ => match s.contains(",") {
true => {
let parts = s.split(',').collect::<Vec<_>>();

if parts.len() != 2 {
Err(TimespecParsingError)?
}

let (month_name, day_number) = parse_month_and_day(&parts[0])?;
let year_number = YearNumber::from_str(&parts[1])?;

Self::MontDayYear {
month_name,
day_number,
year_number,
}
}
false => match DayOfWeek::from_str(s) {
Ok(day) => Self::DayOfWeek(day),
Err(_) => {
let (month_name, day_number) = parse_month_and_day(s)?;

Self::MontDay {
month_name,
day_number,
}
}
},
},
};

fn parse_month_and_day(
s: &str,
) -> Result<(MonthName, DayNumber), TimespecParsingError> {
let month = s
.chars()
.take_while(|this| !this.is_numeric())
.collect::<String>()
.parse::<MonthName>()?;

let day = s
.chars()
.skip_while(|this| !this.is_numeric())
.collect::<String>()
.parse::<DayNumber>()?;

Ok((month, day))
}

Ok(result)
}
}
}

mod tokens {
Expand Down Expand Up @@ -701,21 +784,57 @@ mod tokens {
/// implementation-defined format.
pub struct TimezoneName(String);

impl FromStr for TimezoneName {
type Err = TokenParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
todo!()
}
}

/// One of the values from the mon or abmon keywords in the LC_TIME
/// locale category.
pub struct MonthName(String);

impl FromStr for MonthName {
type Err = TokenParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
todo!()
}
}

/// One of the values from the day or abday keywords in the LC_TIME
/// locale category.
pub struct DayOfWeek(String);

impl FromStr for DayOfWeek {
type Err = TokenParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
todo!()
}
}

/// One of the values from the am_pm keyword in the LC_TIME locale
/// category.
pub enum AmPm {
Am,
Pm,
}

impl FromStr for AmPm {
type Err = TokenParsingError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s.to_lowercase().as_str() {
"am" => Self::Am,
"pm" => Self::Pm,
_ => Err(TokenParsingError)?,
})
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down

0 comments on commit f8cd5d8

Please sign in to comment.