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
124 changes: 29 additions & 95 deletions src/components/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

// TODO: It may finally be time to clean up API to use `IsoDate` and `DateDuration` directly.

use alloc::borrow::ToOwned;
use alloc::string::String;
use alloc::vec::Vec;
use core::str::FromStr;
Expand Down Expand Up @@ -207,67 +206,6 @@ impl FromStr for Calendar {
}
}

// TODO: Potentially dead code.
/// Designate the type of `CalendarFields` needed
#[derive(Debug, Clone, Copy)]
pub enum CalendarFieldsType {
/// Whether the Fields should return for a PlainDate.
Date,
/// Whether the Fields should return for a PlainYearMonth.
YearMonth,
/// Whether the Fields should return for a PlainMonthDay.
MonthDay,
}

// TODO: Optimize to TinyStr or &str.
impl From<&[String]> for CalendarFieldsType {
fn from(value: &[String]) -> Self {
let year_present = value.contains(&"year".to_owned());
let day_present = value.contains(&"day".to_owned());

if year_present && day_present {
CalendarFieldsType::Date
} else if year_present {
CalendarFieldsType::YearMonth
} else {
CalendarFieldsType::MonthDay
}
}
}

/// The `DateLike` objects that can be provided to the `CalendarProtocol`.
#[derive(Debug)]
pub enum CalendarDateLike<'a> {
/// Represents a `PlainDateTime`.
DateTime(&'a PlainDateTime),
/// Represents a `PlainDate`.
Date(&'a PlainDate),
/// Represents a `PlainYearMonth`.
YearMonth(&'a PlainYearMonth),
/// Represents a `PlainMonthDay`.
MonthDay(&'a PlainMonthDay),
}

impl CalendarDateLike<'_> {
/// Retrieves the internal `IsoDate` field.
#[inline]
#[must_use]
pub fn as_iso_date(&self) -> IsoDate {
match self {
CalendarDateLike::DateTime(dt) => dt.iso.date,
CalendarDateLike::Date(d) => d.iso,
CalendarDateLike::YearMonth(ym) => ym.iso,
CalendarDateLike::MonthDay(md) => md.iso,
}
}
}

/// A trait for retrieving an internal calendar slice.
pub trait GetTemporalCalendar {
/// Returns the `TemporalCalendar` value of the implementor.
fn get_calendar(&self) -> Calendar;
}

// ==== Public `CalendarSlot` methods ====

impl Calendar {
Expand Down Expand Up @@ -422,84 +360,80 @@ impl Calendar {
}

/// `CalendarEra`
pub fn era(&self, date_like: &CalendarDateLike) -> TemporalResult<Option<TinyAsciiStr<16>>> {
pub fn era(&self, iso_date: &IsoDate) -> TemporalResult<Option<TinyAsciiStr<16>>> {
if self.is_iso() {
return Ok(None);
}
let calendar_date = self.0.date_from_iso(date_like.as_iso_date().as_icu4x()?);
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.year(&calendar_date).standard_era().map(|era| era.0))
}

/// `CalendarEraYear`
pub fn era_year(&self, date_like: &CalendarDateLike) -> TemporalResult<Option<i32>> {
pub fn era_year(&self, iso_date: &IsoDate) -> TemporalResult<Option<i32>> {
if self.is_iso() {
return Ok(None);
}
let calendar_date = self.0.date_from_iso(date_like.as_iso_date().as_icu4x()?);
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.year(&calendar_date).era_year())
}

/// `CalendarYear`
pub fn year(&self, date_like: &CalendarDateLike) -> TemporalResult<i32> {
pub fn year(&self, iso_date: &IsoDate) -> TemporalResult<i32> {
if self.is_iso() {
return Ok(date_like.as_iso_date().year);
return Ok(iso_date.year);
}
let calendar_date = self.0.date_from_iso(date_like.as_iso_date().as_icu4x()?);
let calendar_date = self.0.date_from_iso(iso_date.as_icu4x()?);
Ok(self.0.year(&calendar_date).extended_year)
}

/// `CalendarMonth`
pub fn month(&self, date_like: &CalendarDateLike) -> TemporalResult<u8> {
pub fn month(&self, iso_date: &IsoDate) -> TemporalResult<u8> {
if self.is_iso() {
return Ok(date_like.as_iso_date().month);
return Ok(iso_date.month);
}

Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarMonthCode`
pub fn month_code(&self, date_like: &CalendarDateLike) -> TemporalResult<TinyAsciiStr<4>> {
pub fn month_code(&self, iso_date: &IsoDate) -> TemporalResult<TinyAsciiStr<4>> {
if self.is_iso() {
return Ok(date_like.as_iso_date().as_icu4x()?.month().standard_code.0);
return Ok(iso_date.as_icu4x()?.month().standard_code.0);
}

Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarDay`
pub fn day(&self, date_like: &CalendarDateLike) -> TemporalResult<u8> {
pub fn day(&self, iso_date: &IsoDate) -> TemporalResult<u8> {
if self.is_iso() {
return Ok(date_like.as_iso_date().day);
return Ok(iso_date.day);
}

Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarDayOfWeek`
pub fn day_of_week(&self, date_like: &CalendarDateLike) -> TemporalResult<u16> {
pub fn day_of_week(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(date_like.as_iso_date().as_icu4x()?.day_of_week() as u16);
return Ok(iso_date.as_icu4x()?.day_of_week() as u16);
}

Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarDayOfYear`
pub fn day_of_year(&self, date_like: &CalendarDateLike) -> TemporalResult<u16> {
pub fn day_of_year(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(date_like
.as_iso_date()
.as_icu4x()?
.day_of_year_info()
.day_of_year);
return Ok(iso_date.as_icu4x()?.day_of_year_info().day_of_year);
}
Err(TemporalError::range().with_message("Not yet implemented."))?
}

/// `CalendarWeekOfYear`
pub fn week_of_year(&self, date_like: &CalendarDateLike) -> TemporalResult<Option<u16>> {
pub fn week_of_year(&self, iso_date: &IsoDate) -> TemporalResult<Option<u16>> {
if self.is_iso() {
let date = date_like.as_iso_date().as_icu4x()?;
let date = iso_date.as_icu4x()?;

let week_calculator = WeekCalculator::default();

Expand All @@ -511,9 +445,9 @@ impl Calendar {
}

/// `CalendarYearOfWeek`
pub fn year_of_week(&self, date_like: &CalendarDateLike) -> TemporalResult<Option<i32>> {
pub fn year_of_week(&self, iso_date: &IsoDate) -> TemporalResult<Option<i32>> {
if self.is_iso() {
let date = date_like.as_iso_date().as_icu4x()?;
let date = iso_date.as_icu4x()?;

let week_calculator = WeekCalculator::default();

Expand All @@ -529,42 +463,42 @@ impl Calendar {
}

/// `CalendarDaysInWeek`
pub fn days_in_week(&self, _date_like: &CalendarDateLike) -> TemporalResult<u16> {
pub fn days_in_week(&self, _iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(7);
}
Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarDaysInMonth`
pub fn days_in_month(&self, date_like: &CalendarDateLike) -> TemporalResult<u16> {
pub fn days_in_month(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(date_like.as_iso_date().as_icu4x()?.days_in_month() as u16);
return Ok(iso_date.as_icu4x()?.days_in_month() as u16);
}
Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarDaysInYear`
pub fn days_in_year(&self, date_like: &CalendarDateLike) -> TemporalResult<u16> {
pub fn days_in_year(&self, iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(date_like.as_iso_date().as_icu4x()?.days_in_year());
return Ok(iso_date.as_icu4x()?.days_in_year());
}

Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarMonthsInYear`
pub fn months_in_year(&self, _date_like: &CalendarDateLike) -> TemporalResult<u16> {
pub fn months_in_year(&self, _iso_date: &IsoDate) -> TemporalResult<u16> {
if self.is_iso() {
return Ok(12);
}
Err(TemporalError::range().with_message("Not yet implemented."))
}

/// `CalendarInLeapYear`
pub fn in_leap_year(&self, date_like: &CalendarDateLike) -> TemporalResult<bool> {
pub fn in_leap_year(&self, iso_date: &IsoDate) -> TemporalResult<bool> {
if self.is_iso() {
return Ok(date_like.as_iso_date().as_icu4x()?.is_in_leap_year());
return Ok(iso_date.as_icu4x()?.is_in_leap_year());
}
Err(TemporalError::range().with_message("Not yet implemented."))
}
Expand Down
48 changes: 19 additions & 29 deletions src/components/date.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
//! This module implements `Date` and any directly related algorithms.

use crate::{
components::{
calendar::{Calendar, CalendarDateLike, GetTemporalCalendar},
duration::DateDuration,
Duration, PlainDateTime,
},
components::{calendar::Calendar, duration::DateDuration, Duration, PlainDateTime},
iso::{IsoDate, IsoDateTime, IsoTime},
options::{
ArithmeticOverflow, DifferenceOperation, DifferenceSettings, DisplayCalendar,
Expand Down Expand Up @@ -486,75 +482,75 @@ impl PlainDate {
impl PlainDate {
/// Returns the calendar year value.
pub fn year(&self) -> TemporalResult<i32> {
self.calendar.year(&CalendarDateLike::Date(self))
self.calendar.year(&self.iso)
}

/// Returns the calendar month value.
pub fn month(&self) -> TemporalResult<u8> {
self.calendar.month(&CalendarDateLike::Date(self))
self.calendar.month(&self.iso)
}

/// Returns the calendar month code value.
pub fn month_code(&self) -> TemporalResult<TinyAsciiStr<4>> {
self.calendar.month_code(&CalendarDateLike::Date(self))
self.calendar.month_code(&self.iso)
}

/// Returns the calendar day value.
pub fn day(&self) -> TemporalResult<u8> {
self.calendar.day(&CalendarDateLike::Date(self))
self.calendar.day(&self.iso)
}

/// Returns the calendar day of week value.
pub fn day_of_week(&self) -> TemporalResult<u16> {
self.calendar.day_of_week(&CalendarDateLike::Date(self))
self.calendar.day_of_week(&self.iso)
}

/// Returns the calendar day of year value.
pub fn day_of_year(&self) -> TemporalResult<u16> {
self.calendar.day_of_year(&CalendarDateLike::Date(self))
self.calendar.day_of_year(&self.iso)
}

/// Returns the calendar week of year value.
pub fn week_of_year(&self) -> TemporalResult<Option<u16>> {
self.calendar.week_of_year(&CalendarDateLike::Date(self))
self.calendar.week_of_year(&self.iso)
}

/// Returns the calendar year of week value.
pub fn year_of_week(&self) -> TemporalResult<Option<i32>> {
self.calendar.year_of_week(&CalendarDateLike::Date(self))
self.calendar.year_of_week(&self.iso)
}

/// Returns the calendar days in week value.
pub fn days_in_week(&self) -> TemporalResult<u16> {
self.calendar.days_in_week(&CalendarDateLike::Date(self))
self.calendar.days_in_week(&self.iso)
}

/// Returns the calendar days in month value.
pub fn days_in_month(&self) -> TemporalResult<u16> {
self.calendar.days_in_month(&CalendarDateLike::Date(self))
self.calendar.days_in_month(&self.iso)
}

/// Returns the calendar days in year value.
pub fn days_in_year(&self) -> TemporalResult<u16> {
self.calendar.days_in_year(&CalendarDateLike::Date(self))
self.calendar.days_in_year(&self.iso)
}

/// Returns the calendar months in year value.
pub fn months_in_year(&self) -> TemporalResult<u16> {
self.calendar.months_in_year(&CalendarDateLike::Date(self))
self.calendar.months_in_year(&self.iso)
}

/// Returns returns whether the date in a leap year for the given calendar.
pub fn in_leap_year(&self) -> TemporalResult<bool> {
self.calendar.in_leap_year(&CalendarDateLike::Date(self))
self.calendar.in_leap_year(&self.iso)
}

pub fn era(&self) -> TemporalResult<Option<TinyAsciiStr<16>>> {
self.calendar.era(&CalendarDateLike::Date(self))
self.calendar.era(&self.iso)
}

pub fn era_year(&self) -> TemporalResult<Option<i32>> {
self.calendar.era_year(&CalendarDateLike::Date(self))
self.calendar.era_year(&self.iso)
}
}

Expand All @@ -570,13 +566,13 @@ impl PlainDate {
pub fn to_date_time(&self, time: Option<PlainTime>) -> TemporalResult<PlainDateTime> {
let time = time.unwrap_or_default();
let iso = IsoDateTime::new(self.iso, time.iso)?;
Ok(PlainDateTime::new_unchecked(iso, self.get_calendar()))
Ok(PlainDateTime::new_unchecked(iso, self.calendar().clone()))
}

/// Converts the current `Date<C>` into a `PlainYearMonth`
#[inline]
pub fn to_year_month(&self) -> TemporalResult<PlainYearMonth> {
self.get_calendar().year_month_from_partial(
self.calendar().year_month_from_partial(
&PartialDate::default().with_fallback_date(self)?,
ArithmeticOverflow::Constrain,
)
Expand All @@ -585,7 +581,7 @@ impl PlainDate {
/// Converts the current `Date<C>` into a `PlainMonthDay`
#[inline]
pub fn to_month_day(&self) -> TemporalResult<PlainMonthDay> {
self.get_calendar().month_day_from_partial(
self.calendar().month_day_from_partial(
&PartialDate::default().with_fallback_date(self)?,
ArithmeticOverflow::Constrain,
)
Expand All @@ -602,12 +598,6 @@ impl PlainDate {

// ==== Trait impls ====

impl GetTemporalCalendar for PlainDate {
fn get_calendar(&self) -> Calendar {
self.calendar.clone()
}
}

impl From<PlainDateTime> for PlainDate {
fn from(value: PlainDateTime) -> Self {
PlainDate::new_unchecked(value.iso.date, value.calendar().clone())
Expand Down
Loading