Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/builtins/core/calendar/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::{TemporalError, TemporalResult};

use crate::builtins::core::{calendar::Calendar, PartialDate};

use super::era::ISO_ERA;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ResolutionType {
Date,
Expand All @@ -34,7 +36,7 @@ impl ResolvedCalendarFields {
overflow: ArithmeticOverflow,
resolve_type: ResolutionType,
) -> TemporalResult<Self> {
let era_year = EraYear::try_from_partial_date(partial_date)?;
let era_year = EraYear::try_from_partial_date(partial_date, resolve_type)?;
if partial_date.calendar.is_iso() {
let month_code = resolve_iso_month(partial_date, overflow)?;
let day = resolve_day(partial_date.day, resolve_type == ResolutionType::YearMonth)?;
Expand Down Expand Up @@ -85,7 +87,10 @@ pub struct EraYear {
}

impl EraYear {
pub(crate) fn try_from_partial_date(partial: &PartialDate) -> TemporalResult<Self> {
pub(crate) fn try_from_partial_date(
partial: &PartialDate,
resolution_type: ResolutionType,
) -> TemporalResult<Self> {
match (partial.year, partial.era, partial.era_year) {
(Some(year), None, None) => {
let Some(era) = partial.calendar.get_calendar_default_era() else {
Expand All @@ -112,6 +117,10 @@ impl EraYear {
era: Era(era_info.name),
})
}
(None, None, None) if resolution_type == ResolutionType::MonthDay => Ok(Self {
era: Era(ISO_ERA.name),
year: 1972,
}),
_ => Err(TemporalError::r#type()
.with_message("Required fields missing to determine an era and year.")),
}
Expand Down
66 changes: 62 additions & 4 deletions src/builtins/core/month_day.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
Calendar, MonthCode, TemporalError, TemporalResult, TemporalUnwrap,
};

use super::{PartialDate, PlainDate};
use super::{calendar::month_to_month_code, PartialDate, PlainDate};
use writeable::Writeable;

/// The native Rust implementation of `Temporal.PlainMonthDay`
Expand Down Expand Up @@ -82,12 +82,45 @@ impl PlainMonthDay {
)
}

/// Create a `PlainMonthDay` with the provided fields from a [`PartialDate`].
pub fn with(
&self,
_partial: PartialDate,
_overflow: ArithmeticOverflow,
partial: PartialDate,
overflow: Option<ArithmeticOverflow>,
) -> TemporalResult<Self> {
Err(TemporalError::general("Not yet implemented."))
// Steps 1-6 are engine specific.
// 5. Let fields be ISODateToFields(calendar, monthDay.[[ISODate]], month-day).
// 6. Let partialMonthDay be ? PrepareCalendarFields(calendar, temporalMonthDayLike, « year, month, month-code, day », « », partial).
//
// NOTE: We assert that partial is not empty per step 6
if partial.is_empty() {
return Err(TemporalError::r#type().with_message("partial object must have a field."));
}

// NOTE: We only need to set month / month_code and day, per spec.
// 7. Set fields to CalendarMergeFields(calendar, fields, partialMonthDay).
let (month, month_code) = match (partial.month, partial.month_code) {
(Some(m), Some(mc)) => (Some(m), Some(mc)),
(Some(m), None) => (Some(m), Some(month_to_month_code(m)?)),
(None, Some(mc)) => (Some(mc.to_month_integer()), Some(mc)),
(None, None) => (
Some(self.month_code().to_month_integer()),
Some(self.month_code()),
),
};
let merged_day = partial.day.unwrap_or(self.day());
let merged = partial
.with_month(month)
.with_month_code(month_code)
.with_day(Some(merged_day));

// Step 8-9 already handled by engine.
// 8. Let resolvedOptions be ? GetOptionsObject(options).
// 9. Let overflow be ? GetTemporalOverflowOption(resolvedOptions).
// 10. Let isoDate be ? CalendarMonthDayFromFields(calendar, fields, overflow).
// 11. Return ! CreateTemporalMonthDay(isoDate, calendar).
self.calendar
.month_day_from_partial(&merged, overflow.unwrap_or(ArithmeticOverflow::Constrain))
}

/// Returns the ISO day value of `PlainMonthDay`.
Expand Down Expand Up @@ -137,6 +170,7 @@ impl PlainMonthDay {
self.calendar.day(&self.iso)
}

/// Create a [`PlainDate`] from the current `PlainMonthDay`.
pub fn to_plain_date(&self, year: Option<PartialDate>) -> TemporalResult<PlainDate> {
let year_partial = match &year {
Some(partial) => partial,
Expand Down Expand Up @@ -164,6 +198,7 @@ impl PlainMonthDay {
.date_from_partial(&partial_date, ArithmeticOverflow::Reject)
}

/// Creates a RFC9557 IXDTF string from the current `PlainMonthDay`.
pub fn to_ixdtf_string(&self, display_calendar: DisplayCalendar) -> String {
self.to_ixdtf_writeable(display_calendar)
.write_to_string()
Expand Down Expand Up @@ -197,6 +232,29 @@ mod tests {
use crate::Calendar;
use tinystr::tinystr;

#[test]
fn test_plain_month_day_with() {
let month_day = PlainMonthDay::from_utf8("01-15".as_bytes()).unwrap();

let new = month_day
.with(PartialDate::new().with_day(Some(22)), None)
.unwrap();
assert_eq!(
new.month_code(),
MonthCode::try_from_utf8("M01".as_bytes()).unwrap()
);
assert_eq!(new.day(), 22,);

let new = month_day
.with(PartialDate::new().with_month(Some(12)), None)
.unwrap();
assert_eq!(
new.month_code(),
MonthCode::try_from_utf8("M12".as_bytes()).unwrap()
);
assert_eq!(new.day(), 15,);
}

#[test]
fn test_to_plain_date_with_year() {
let month_day = PlainMonthDay::new_with_overflow(
Expand Down
2 changes: 1 addition & 1 deletion temporal_capi/bindings/c/PlainMonthDay.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.d.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions temporal_capi/bindings/cpp/temporal_rs/PlainMonthDay.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions temporal_capi/src/plain_month_day.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ pub mod ffi {
pub fn with(
&self,
partial: PartialDate,
overflow: ArithmeticOverflow,
overflow: Option<ArithmeticOverflow>,
) -> Result<Box<PlainMonthDay>, TemporalError> {
self.0
.with(partial.try_into()?, overflow.into())
.with(partial.try_into()?, overflow.map(Into::into))
.map(|x| Box::new(PlainMonthDay(x)))
.map_err(Into::into)
}
Expand Down
Loading