Skip to content

Commit b6514d7

Browse files
sebastianjacmattdependabot[bot]lockels
authored
Add with to PlainYearMonth (#231)
Restructured pull request of #216 Worked with @HenrikTennebekk on #143 Had to change temporal_capi/plain_year_month.rs hope this is fine? --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: lockels <123327897+lockels@users.noreply.github.com>
1 parent 5d21776 commit b6514d7

File tree

5 files changed

+112
-22
lines changed

5 files changed

+112
-22
lines changed

src/builtins/core/date.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,18 @@ impl PartialDate {
7878
})
7979
}
8080

81-
crate::impl_with_fallback_method!(with_fallback_date, PlainDate);
82-
crate::impl_with_fallback_method!(with_fallback_datetime, PlainDateTime);
81+
crate::impl_with_fallback_method!(with_fallback_year_month, () PlainYearMonth); // excludes day
82+
crate::impl_with_fallback_method!(with_fallback_date, (with_day: day) PlainDate);
83+
crate::impl_with_fallback_method!(with_fallback_datetime, (with_day:day) PlainDateTime);
84+
8385
// TODO: ZonedDateTime
8486
}
8587

8688
// Use macro to impl fallback methods to avoid having a trait method.
8789
#[doc(hidden)]
8890
#[macro_export]
8991
macro_rules! impl_with_fallback_method {
90-
($method_name:ident, $component_type:ty) => {
92+
($method_name:ident, ( $(with_day: $day:ident)? ) $component_type:ty) => {
9193
pub(crate) fn $method_name(&self, fallback: &$component_type) -> TemporalResult<Self> {
9294
let era = if let Some(era) = self.era {
9395
Some(era)
@@ -112,16 +114,18 @@ macro_rules! impl_with_fallback_method {
112114
Some(fallback.month_code()),
113115
),
114116
};
115-
116-
Ok(Self {
117-
year: Some(self.year.unwrap_or(fallback.year())),
118-
month,
119-
month_code,
120-
day: Some(self.day.unwrap_or(fallback.day().into())),
121-
era,
122-
era_year,
123-
calendar: fallback.calendar().clone(),
124-
})
117+
#[allow(clippy::needless_update)] {
118+
Ok(Self {
119+
year: Some(self.year.unwrap_or(fallback.year())),
120+
month,
121+
month_code,
122+
$($day: Some(self.day.unwrap_or(fallback.day().into())),)?
123+
era,
124+
era_year,
125+
calendar: fallback.calendar().clone(),
126+
..Default::default()
127+
})
128+
}
125129
}
126130
};
127131
}

src/builtins/core/year_month.rs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,24 @@ impl PlainYearMonth {
183183
/// Creates a `PlainYearMonth` using the fields provided from a [`PartialDate`]
184184
pub fn with(
185185
&self,
186-
_partial: PartialDate,
187-
_overflow: ArithmeticOverflow,
186+
partial: PartialDate,
187+
overflow: Option<ArithmeticOverflow>,
188188
) -> TemporalResult<Self> {
189-
Err(TemporalError::general("Not yet implemented."))
189+
// 1. Let yearMonth be the this value.
190+
// 2. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]).
191+
// 3. If ? IsPartialTemporalObject(temporalYearMonthLike) is false, throw a TypeError exception.
192+
// 4. Let calendar be yearMonth.[[Calendar]].
193+
// 5. Let fields be ISODateToFields(calendar, yearMonth.[[ISODate]], year-month).
194+
// 6. Let partialYearMonth be ? PrepareCalendarFields(calendar, temporalYearMonthLike, « year, month, month-code », « », partial).
195+
// 7. Set fields to CalendarMergeFields(calendar, fields, partialYearMonth).
196+
// 8. Let resolvedOptions be ? GetOptionsObject(options).
197+
// 9. Let overflow be ? GetTemporalOverflowOption(resolvedOptions).
198+
// 10. Let isoDate be ? CalendarYearMonthFromFields(calendar, fields, overflow).
199+
// 11. Return ! CreateTemporalYearMonth(isoDate, calendar).
200+
self.calendar.year_month_from_partial(
201+
&partial.with_fallback_year_month(self)?,
202+
overflow.unwrap_or(ArithmeticOverflow::Constrain),
203+
)
190204
}
191205

192206
/// Compares one `PlainYearMonth` to another `PlainYearMonth` using their
@@ -298,6 +312,78 @@ mod tests {
298312

299313
use super::PlainYearMonth;
300314

315+
use tinystr::tinystr;
316+
317+
use super::*;
318+
319+
#[test]
320+
fn test_plain_year_month_with() {
321+
let base = PlainYearMonth::new_with_overflow(
322+
2025,
323+
3,
324+
None,
325+
Calendar::default(),
326+
ArithmeticOverflow::Reject,
327+
)
328+
.unwrap();
329+
330+
// Year
331+
let partial = PartialDate {
332+
year: Some(2001),
333+
..Default::default()
334+
};
335+
336+
let with_year = base.with(partial, None).unwrap();
337+
assert_eq!(with_year.iso_year(), 2001); // year is changed
338+
assert_eq!(with_year.iso_month(), 3); // month is not changed
339+
assert_eq!(with_year.month_code(), MonthCode::from_str("M03").unwrap()); // assert month code has been initialized correctly
340+
341+
// Month
342+
let partial = PartialDate {
343+
month: Some(2),
344+
..Default::default()
345+
};
346+
let with_month = base.with(partial, None).unwrap();
347+
assert_eq!(with_month.iso_year(), 2025); // year is not changed
348+
assert_eq!(with_month.iso_month(), 2); // month is changed
349+
assert_eq!(with_month.month_code(), MonthCode::from_str("M02").unwrap()); // assert month code has changed as well as month
350+
351+
// Month Code
352+
let partial = PartialDate {
353+
month_code: Some(MonthCode(tinystr!(4, "M05"))), // change month to May (5)
354+
..Default::default()
355+
};
356+
let with_month_code = base.with(partial, None).unwrap();
357+
assert_eq!(with_month_code.iso_year(), 2025); // year is not changed
358+
assert_eq!(
359+
with_month_code.month_code(),
360+
MonthCode::from_str("M05").unwrap()
361+
); // assert month code has changed
362+
assert_eq!(with_month_code.iso_month(), 5); // month is changed as well
363+
364+
// Day
365+
let partial = PartialDate {
366+
day: Some(15),
367+
..Default::default()
368+
};
369+
let with_day = base.with(partial, None).unwrap();
370+
assert_eq!(with_day.iso_year(), 2025); // year is not changed
371+
assert_eq!(with_day.iso_month(), 3); // month is not changed
372+
assert_eq!(with_day.iso.day, 1); // day is ignored
373+
374+
// All
375+
let partial = PartialDate {
376+
year: Some(2001),
377+
month: Some(2),
378+
day: Some(15),
379+
..Default::default()
380+
};
381+
let with_all = base.with(partial, None).unwrap();
382+
assert_eq!(with_all.iso_year(), 2001); // year is changed
383+
assert_eq!(with_all.iso_month(), 2); // month is changed
384+
assert_eq!(with_all.iso.day, 1); // day is ignored
385+
}
386+
301387
#[test]
302388
fn basic_from_str() {
303389
let valid_strings = [

temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.d.hpp

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

temporal_capi/bindings/cpp/temporal_rs/PlainYearMonth.hpp

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

temporal_capi/src/plain_year_month.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ pub mod ffi {
3636
pub fn with(
3737
&self,
3838
partial: PartialDate,
39-
overflow: ArithmeticOverflow,
39+
overflow: Option<ArithmeticOverflow>,
4040
) -> Result<Box<Self>, TemporalError> {
4141
self.0
42-
.with(partial.try_into()?, overflow.into())
42+
.with(partial.try_into()?, overflow.map(Into::into))
4343
.map(|x| Box::new(Self(x)))
4444
.map_err(Into::into)
4545
}

0 commit comments

Comments
 (0)