Skip to content

Conversation

@robertbastian
Copy link
Member

@robertbastian robertbastian commented Oct 22, 2025

Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly in favor of this, but it shouldn't touch DateFields

}

/// Constructs a non-leap with with the given number.
pub const fn new(number: u8) -> Self {
Copy link
Member

@sffc sffc Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I think I prefer new_common() / new_normal() and new_leap() over new() and new().leap()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking here is that the vast majority of calls will be for non-lunisolar calendars, where the concept of a "normal month" is more confusing than helpful. It's just a month, and you can make it into a leap month if needed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think new/new_leap is fine, but I'm not really sure what I prefer here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm okay landing this now and bikeshedding it later

/// For a full example, see [`Self::ordinal_month`].
pub month_code: Option<&'a [u8]>,
/// See [`MonthInfo::ordinal`](crate::types::MonthInfo::ordinal).
pub month: Option<Month>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: This should continue to accept a stringy month code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will split that discussion into a separate PR I guess

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New idea: we add a new field called month, keep month_code, and rename era to era_code.

We already have code to resolve conflicts between month_code and ordinal_month and we can easily throw month into that resolver.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable

@robertbastian robertbastian force-pushed the month branch 2 times, most recently from 754fcdf to bbaf993 Compare November 6, 2025 16:33
Copy link
Member

@Manishearth Manishearth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the effect this has on the tests

pub(crate) formatting: Month,
}

impl core::ops::Deref for MonthInfo {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: we shouldn't do this, this is considered bad practice for non-pointers.

https://users.rust-lang.org/t/understanding-the-perils-of-deref/47958

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, any idea how to not duplicate the is_leap and number methods on both Month and MonthInfo but also not have something like date.month().standard().number()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to duplicate them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we shouldn't require people to call that method chain to get the number

self.standard.is_leap()
}

#[doc(hidden)] // exposed, not a great name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: probably mention who the user is. I think icu_datetime.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not even, datetime uses the formatting_ getters. we don't use this anywhere, but we released it in 2.1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to not change a public API into a hidden API in this pull request. This is a perfectly valid public API aimed at clients, not just ICU4X components, that has been public since at least 2.0 and maybe longer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MonthInfo was new in 2.0. It came initially with three public fields and two functions, month_number being one.

https://docs.rs/icu_calendar/2.0.6/icu_calendar/types/struct.MonthInfo.html#method.month_number

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I guess 2.0, I'd prefer deprecating it then. It's just not a great name to have date.month().month_number(), the second month is redundant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, please call out public API changes like this, we shouldn't have to figure it out.

I noticed it, assumed from the comment that it was internal, left my comment and decided to come back to it when I had more time after lunch. Probably would have noticed when I looked closer but ideally I don't have to try and second guess everything for public API changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

semver CI did call this out

Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed down through types.rs

pub(crate) enum MonthCodeParseError {
#[non_exhaustive]
pub enum MonthCodeParseError {
/// Invalid syntax
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit

Suggested change
/// Invalid syntax
/// The month code syntax is invalid.

and please add an example.

/// A [`MonthCode`] that has been parsed into its internal representation.
#[derive(Copy, Clone, Debug, PartialEq)]
pub(crate) struct ValidMonthCode {
/// A representation of a month.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Needs much more docs.


#[doc(hidden)]
#[doc(hidden)] // for formatting
pub fn formatting_month_number(self) -> u8 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I thought icu_datetime would just read the formatting month field from the MonthInfo? Do we need these fns?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah this removes the fallibility of parsing the code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right. Well since this is internal and it is between tilde-dep crates, you should be able to remove these functions if you start publicly exporting the formatting month as a Month.

self.standard.is_leap()
}

#[doc(hidden)] // exposed, not a great name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to not change a public API into a hidden API in this pull request. This is a perfectly valid public API aimed at clients, not just ICU4X components, that has been public since at least 2.0 and maybe longer.

@sffc
Copy link
Member

sffc commented Nov 6, 2025

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new Month type to represent calendar months, replacing the previous MonthCode and ValidMonthCode types. This is a significant and positive refactoring that improves type safety and API clarity. The changes are applied consistently across the calendar component, including core logic, tests, benchmarks, and FFI bindings. My review found one minor issue where a newly hidden API is used in a doc test, which should be updated to use the new public API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants