Skip to content

Commit 172fe64

Browse files
committed
use temporal parser in from_utf8
1 parent d32b58d commit 172fe64

File tree

5 files changed

+56
-69
lines changed

5 files changed

+56
-69
lines changed

src/builtins/core/datetime.rs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ use crate::{
1212
DisplayCalendar, ResolvedRoundingOptions, RoundingOptions, ToStringRoundingOptions, Unit,
1313
UnitGroup,
1414
},
15-
parsers::{parse_date_time, IxdtfStringBuilder},
15+
parsers::{IxdtfStringBuilder, TemporalParser},
1616
primitive::FiniteF64,
1717
provider::{NeverProvider, TimeZoneProvider},
18-
temporal_assert, MonthCode, TemporalError, TemporalResult, TemporalUnwrap, TimeZone,
18+
temporal_assert, MonthCode, TemporalError, TemporalResult, TimeZone,
1919
};
2020
use alloc::string::String;
2121
use core::{cmp::Ordering, str::FromStr};
@@ -549,30 +549,17 @@ impl PlainDateTime {
549549

550550
// Converts a UTF-8 encoded string into a `PlainDateTime`.
551551
pub fn from_utf8(s: &[u8]) -> TemporalResult<Self> {
552-
let parse_record = parse_date_time(s)?;
553-
554-
let calendar = parse_record
555-
.calendar
556-
.map(Calendar::try_from_utf8)
557-
.transpose()?
558-
.unwrap_or_default();
559-
560-
let time = parse_record
561-
.time
562-
.map(IsoTime::from_time_record)
563-
.transpose()?
564-
.unwrap_or_default();
565-
566-
let parsed_date = parse_record.date.temporal_unwrap()?;
567-
568-
let date = IsoDate::new_with_overflow(
569-
parsed_date.year,
570-
parsed_date.month,
571-
parsed_date.day,
572-
ArithmeticOverflow::Reject,
573-
)?;
552+
let parser = TemporalParser::new();
553+
let parsed = parser.parse_date_time(core::str::from_utf8(s)
554+
.map_err(|_| TemporalError::syntax().with_message("Invalid UTF-8 in datetime string"))?)?;
555+
556+
let calendar = if let Some(cal_str) = &parsed.calendar {
557+
Calendar::try_from_utf8(cal_str.as_bytes())?
558+
} else {
559+
Calendar::default()
560+
};
574561

575-
Ok(Self::new_unchecked(IsoDateTime::new(date, time)?, calendar))
562+
Ok(Self::new_unchecked(parsed.iso, calendar))
576563
}
577564

578565
/// Creates a new `DateTime` with the fields of a `PartialDateTime`.

src/builtins/core/instant.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
DifferenceOperation, DifferenceSettings, DisplayOffset, ResolvedRoundingOptions,
1313
RoundingOptions, ToStringRoundingOptions, Unit, UnitGroup,
1414
},
15-
parsers::{parse_instant, IxdtfStringBuilder},
15+
parsers::{IxdtfStringBuilder, TemporalParser},
1616
provider::TimeZoneProvider,
1717
rounding::{IncrementRounder, Round},
1818
unix_time::EpochNanoseconds,
@@ -278,10 +278,12 @@ impl Instant {
278278

279279
// Converts a UTF-8 encoded string into a `Instant`.
280280
pub fn from_utf8(s: &[u8]) -> TemporalResult<Self> {
281-
let ixdtf_record = parse_instant(s)?;
281+
let parser = TemporalParser::new();
282+
let parsed = parser.parse_instant(core::str::from_utf8(s)
283+
.map_err(|_| TemporalError::syntax().with_message("Invalid UTF-8 in instant string"))?)?;
282284

283-
// Find the offset
284-
let ns_offset = match ixdtf_record.offset {
285+
// Find the offset
286+
let ns_offset = match parsed.offset {
285287
UtcOffsetRecordOrZ::Offset(offset) => {
286288
let ns = offset
287289
.fraction()
@@ -296,21 +298,19 @@ impl Instant {
296298
UtcOffsetRecordOrZ::Z => 0,
297299
};
298300

299-
let time_nanoseconds = ixdtf_record
300-
.time
301-
.fraction
302-
.and_then(|x| x.to_nanoseconds())
303-
.unwrap_or(0);
301+
let time_nanoseconds = parsed.iso.time.millisecond as u32 * 1_000_000
302+
+ parsed.iso.time.microsecond as u32 * 1_000
303+
+ parsed.iso.time.nanosecond as u32;
304304
let (millisecond, rem) = time_nanoseconds.div_rem_euclid(&1_000_000);
305305
let (microsecond, nanosecond) = rem.div_rem_euclid(&1_000);
306306

307307
let balanced = IsoDateTime::balance(
308-
ixdtf_record.date.year,
309-
ixdtf_record.date.month.into(),
310-
ixdtf_record.date.day.into(),
311-
ixdtf_record.time.hour.into(),
312-
ixdtf_record.time.minute.into(),
313-
ixdtf_record.time.second.clamp(0, 59).into(),
308+
parsed.iso.date.year,
309+
parsed.iso.date.month.into(),
310+
parsed.iso.date.day.into(),
311+
parsed.iso.time.hour.into(),
312+
parsed.iso.time.minute.into(),
313+
parsed.iso.time.second.clamp(0, 59).into(),
314314
millisecond.into(),
315315
microsecond.into(),
316316
i128::from(nanosecond) - i128::from(ns_offset),

src/builtins/core/month_day.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use core::str::FromStr;
66
use crate::{
77
iso::IsoDate,
88
options::{ArithmeticOverflow, DisplayCalendar},
9-
parsers::{FormattableCalendar, FormattableDate, FormattableMonthDay},
10-
Calendar, MonthCode, TemporalError, TemporalResult, TemporalUnwrap,
9+
parsers::{FormattableCalendar, FormattableDate, FormattableMonthDay, TemporalParser},
10+
Calendar, MonthCode, TemporalError, TemporalResult,
1111
};
1212

1313
use super::{calendar::month_to_month_code, PartialDate, PlainDate};
@@ -189,13 +189,15 @@ impl PlainMonthDay {
189189

190190
// Converts a UTF-8 encoded string into a `PlainMonthDay`.
191191
pub fn from_utf8(s: &[u8]) -> TemporalResult<Self> {
192-
let record = crate::parsers::parse_month_day(s)?;
192+
let parser = TemporalParser::new();
193+
let parsed = parser.parse_month_day(core::str::from_utf8(s)
194+
.map_err(|_| TemporalError::syntax().with_message("Invalid UTF-8 in month-day string"))?)?;
193195

194-
let calendar = record
195-
.calendar
196-
.map(Calendar::try_from_utf8)
197-
.transpose()?
198-
.unwrap_or_default();
196+
let calendar = if let Some(cal_str) = &parsed.calendar {
197+
Calendar::try_from_utf8(cal_str.as_bytes())?
198+
} else {
199+
Calendar::default()
200+
};
199201

200202
// ParseISODateTime
201203
// Step 4.a.ii.3
@@ -206,13 +208,9 @@ impl PlainMonthDay {
206208
return Err(TemporalError::range().with_message("non-ISO calendar not supported."));
207209
}
208210

209-
let date = record.date;
210-
211-
let date = date.temporal_unwrap()?;
212-
213211
Self::new_with_overflow(
214-
date.month,
215-
date.day,
212+
parsed.iso.month,
213+
parsed.iso.day,
216214
calendar,
217215
ArithmeticOverflow::Reject,
218216
None,

src/builtins/core/time.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
ArithmeticOverflow, DifferenceOperation, DifferenceSettings, ResolvedRoundingOptions,
88
RoundingIncrement, RoundingMode, ToStringRoundingOptions, Unit, UnitGroup,
99
},
10-
parsers::{parse_time, IxdtfStringBuilder},
10+
parsers::{IxdtfStringBuilder, TemporalParser},
1111
TemporalError, TemporalResult,
1212
};
1313
use alloc::string::String;
@@ -418,9 +418,10 @@ impl PlainTime {
418418

419419
// Converts a UTF-8 encoded string into a `PlainTime`.
420420
pub fn from_utf8(s: &[u8]) -> TemporalResult<Self> {
421-
let result = parse_time(s)?;
422-
let iso = IsoTime::from_time_record(result)?;
423-
Ok(Self::new_unchecked(iso))
421+
let parser = TemporalParser::new();
422+
let parsed = parser.parse_time(core::str::from_utf8(s)
423+
.map_err(|_| TemporalError::syntax().with_message("Invalid UTF-8 in time string"))?)?;
424+
Ok(Self::new_unchecked(parsed.iso))
424425
}
425426

426427
/// Creates a new `PlainTime` using the current `PlainTime` fields as a fallback.

src/builtins/core/year_month.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use crate::{
1111
ArithmeticOverflow, DifferenceOperation, DifferenceSettings, DisplayCalendar,
1212
ResolvedRoundingOptions, RoundingIncrement, Unit, UnitGroup,
1313
},
14-
parsers::{FormattableCalendar, FormattableDate, FormattableYearMonth},
14+
parsers::{FormattableCalendar, FormattableDate, FormattableYearMonth, TemporalParser},
1515
provider::NeverProvider,
1616
utils::pad_iso_year,
17-
Calendar, MonthCode, TemporalError, TemporalResult, TemporalUnwrap, TimeZone,
17+
Calendar, MonthCode, TemporalError, TemporalResult, TimeZone,
1818
};
1919
use icu_calendar::AnyCalendarKind;
2020

@@ -460,12 +460,15 @@ impl PlainYearMonth {
460460

461461
// Converts a UTF-8 encoded string into a `PlainYearMonth`.
462462
pub fn from_utf8(s: &[u8]) -> TemporalResult<Self> {
463-
let record = crate::parsers::parse_year_month(s)?;
464-
let calendar = record
465-
.calendar
466-
.map(Calendar::try_from_utf8)
467-
.transpose()?
468-
.unwrap_or_default();
463+
let parser = TemporalParser::new();
464+
let parsed = parser.parse_year_month(core::str::from_utf8(s)
465+
.map_err(|_| TemporalError::syntax().with_message("Invalid UTF-8 in year-month string"))?)?;
466+
467+
let calendar = if let Some(cal_str) = &parsed.calendar {
468+
Calendar::try_from_utf8(cal_str.as_bytes())?
469+
} else {
470+
Calendar::default()
471+
};
469472

470473
// ParseISODateTime
471474
// Step 4.a.ii.3
@@ -476,11 +479,9 @@ impl PlainYearMonth {
476479
return Err(TemporalError::range().with_message("non-ISO calendar not supported."));
477480
}
478481

479-
let date = record.date.temporal_unwrap()?;
480-
481482
// The below steps are from `ToTemporalYearMonth`
482483
// 10. Let isoDate be CreateISODateRecord(result.[[Year]], result.[[Month]], result.[[Day]]).
483-
let iso = IsoDate::new_unchecked(date.year, date.month, date.day);
484+
let iso = parsed.iso;
484485

485486
// 11. If ISOYearMonthWithinLimits(isoDate) is false, throw a RangeError exception.
486487
if !year_month_within_limits(iso.year, iso.month) {

0 commit comments

Comments
 (0)