Skip to content

Commit

Permalink
Bug fixes and more implementation (#110)
Browse files Browse the repository at this point in the history
- md_record from parse_ixdtf is enough, we shouldn't need to fall back
to datetime parsing.
- from_str should lowercase the iso8601 (fixes tests)
- Support parsing the ISO string then getting the calendar from that.
- Support ref year

This is to support changes in boa-dev/boa#4034
  • Loading branch information
jasonwilliams authored Nov 26, 2024
1 parent 58a6c56 commit 454d1a8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
14 changes: 12 additions & 2 deletions src/components/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::str::FromStr;

use crate::parsers::parse_date_time;
use crate::{
components::{
duration::{DateDuration, TimeDuration},
Expand Down Expand Up @@ -190,13 +191,21 @@ impl Calendar {
impl FromStr for Calendar {
type Err = TemporalError;

// 13.39 ParseTemporalCalendarString ( string )
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut cal_str = s;
if let Ok(record) = parse_date_time(s) {
if let Some(calendar) = record.calendar {
cal_str = calendar;
}
}

// NOTE(nekesss): Catch the iso identifier here, as `iso8601` is not a valid ID below.
if s == "iso8601" {
if cal_str.to_lowercase() == "iso8601" {
return Ok(Self::default());
}

let Some(cal) = AnyCalendarKind::get_for_bcp47_string(s) else {
let Some(cal) = AnyCalendarKind::get_for_bcp47_string(cal_str) else {
return Err(TemporalError::range().with_message("Not a builtin calendar."));
};

Expand Down Expand Up @@ -322,6 +331,7 @@ impl Calendar {
resolved_fields.day,
self.clone(),
overflow,
None,
);
}

Expand Down
12 changes: 11 additions & 1 deletion src/components/month_day.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ impl PlainMonthDay {
day: i32,
calendar: Calendar,
overflow: ArithmeticOverflow,
ref_year: Option<i32>,
) -> TemporalResult<Self> {
let ry = ref_year.unwrap_or(1972);
// 1972 is the first leap year in the Unix epoch (needed to cover all dates)
let iso = IsoDate::new_with_overflow(1972, month, day, overflow)?;
let iso = IsoDate::new_with_overflow(ry, month, day, overflow)?;
Ok(Self::new_unchecked(iso, calendar))
}

Expand All @@ -56,6 +58,13 @@ impl PlainMonthDay {
self.iso.month
}

// returns the iso year value of `MonthDay`.
#[inline]
#[must_use]
pub fn iso_year(&self) -> i32 {
self.iso.year
}

/// Returns the string identifier for the current calendar used.
#[inline]
#[must_use]
Expand Down Expand Up @@ -108,6 +117,7 @@ impl FromStr for PlainMonthDay {
date.day.into(),
Calendar::from_str(calendar)?,
ArithmeticOverflow::Reject,
None,
)
}
}
14 changes: 2 additions & 12 deletions src/parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,8 @@ pub(crate) fn parse_year_month(source: &str) -> TemporalResult<IxdtfParseRecord>
#[inline]
pub(crate) fn parse_month_day(source: &str) -> TemporalResult<IxdtfParseRecord> {
let md_record = parse_ixdtf(source, ParseVariant::MonthDay);

if let Ok(md) = md_record {
return Ok(md);
}

let dt_parse = parse_ixdtf(source, ParseVariant::DateTime);

match dt_parse {
Ok(dt) => Ok(dt),
// Format and return the error from parsing YearMonth.
_ => md_record.map_err(|e| TemporalError::range().with_message(format!("{e}"))),
}
// Error needs to be a RangeError
md_record.map_err(|e| TemporalError::range().with_message(format!("{e}")))
}

#[inline]
Expand Down

0 comments on commit 454d1a8

Please sign in to comment.