-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add initial calendars crate * rm serde * review fixes * fmt * Move iso constructors to Date * review fixes * rm where * scope Debug bound * construct_unchecked -> from_raw * fmt * add Default * fix clippy * +errors
- Loading branch information
1 parent
085c816
commit 67bd340
Showing
9 changed files
with
618 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# This file is part of ICU4X. For terms of use, please see the file | ||
# called LICENSE at the top level of the ICU4X source tree | ||
# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
|
||
[package] | ||
name = "icu_calendar" | ||
description = "API for supporting various types of calendars" | ||
version = "0.2.0" | ||
authors = ["The ICU4X Project Developers"] | ||
edition = "2018" | ||
readme = "README.md" | ||
repository = "https://github.com/unicode-org/icu4x" | ||
license-file = "../../LICENSE" | ||
categories = ["internationalization"] | ||
# Keep this in sync with other crates unless there are exceptions | ||
include = [ | ||
"src/**/*", | ||
"examples/**/*", | ||
"benches/**/*", | ||
"tests/**/*", | ||
"Cargo.toml", | ||
"README.md" | ||
] | ||
|
||
[package.metadata.docs.rs] | ||
all-features = true | ||
|
||
[package.metadata.cargo-all-features] | ||
skip_optional_dependencies = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// This file is part of ICU4X. For terms of use, please see the file | ||
// called LICENSE at the top level of the ICU4X source tree | ||
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
|
||
use crate::{Date, DateDuration, DurationUnit, Iso}; | ||
|
||
/// A calendar implementation | ||
/// | ||
/// Only implementors of [`Calendar`] should care about these methods, in general users of | ||
/// these calendars should use the methods on [`Date`] instead. | ||
/// | ||
/// Individual [`Calendar`] implementations may have inherent utility methods | ||
/// allowing for direct construction, etc. | ||
pub trait Calendar { | ||
type DateInner: PartialEq + Eq + Clone; | ||
/// Construct the date from an ISO date | ||
fn date_from_iso(&self, iso: Date<Iso>) -> Self::DateInner; | ||
fn date_to_iso(&self, date: &Self::DateInner) -> Date<Iso>; | ||
// fn validate_date(&self, e: Era, y: Year, m: MonthCode, d: Day) -> bool; | ||
// // similar validators for YearMonth, etc | ||
|
||
// fn is_leap<A: AsCalendar<Calendar = Self>>(&self, date: &Date<A>) -> bool; | ||
fn months_in_year(&self, date: &Self::DateInner) -> u8; | ||
fn days_in_year(&self, date: &Self::DateInner) -> u32; | ||
fn days_in_month(&self, date: &Self::DateInner) -> u8; | ||
/// Monday is 1, Sunday is 7, according to ISO | ||
fn day_of_week(&self, date: &Self::DateInner) -> u8 { | ||
self.date_to_iso(date).day_of_week() | ||
} | ||
// fn week_of_year(&self, date: &Self::DateInner) -> u8; | ||
|
||
/// Add `offset` to `date` | ||
fn offset_date(&self, date: &mut Self::DateInner, offset: DateDuration<Self>); | ||
|
||
/// Calculate `date2 - date` as a duration | ||
fn until( | ||
&self, | ||
date1: &Self::DateInner, | ||
date2: &Self::DateInner, | ||
largest_unit: DurationUnit, | ||
smallest_unit: DurationUnit, | ||
) -> DateDuration<Self>; | ||
|
||
fn debug_name() -> &'static str; | ||
// fn since(&self, from: &Date<Self>, to: &Date<Self>) -> Duration<Self>, Error; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// This file is part of ICU4X. For terms of use, please see the file | ||
// called LICENSE at the top level of the ICU4X source tree | ||
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
|
||
use crate::{Calendar, DateDuration, DurationUnit, Iso}; | ||
use std::fmt; | ||
|
||
pub trait AsCalendar { | ||
type Calendar: Calendar; | ||
fn as_calendar(&self) -> &Self::Calendar; | ||
} | ||
|
||
impl<C: Calendar> AsCalendar for C { | ||
type Calendar = C; | ||
#[inline] | ||
fn as_calendar(&self) -> &Self { | ||
self | ||
} | ||
} | ||
|
||
pub struct Date<A: AsCalendar> { | ||
inner: <A::Calendar as Calendar>::DateInner, | ||
calendar: A, | ||
} | ||
|
||
impl<A: AsCalendar> Date<A> { | ||
/// Construct a date from an ISO date and some calendar representation | ||
#[inline] | ||
pub fn new_from_iso(iso: Date<Iso>, calendar: A) -> Self { | ||
let inner = calendar.as_calendar().date_from_iso(iso); | ||
Date { inner, calendar } | ||
} | ||
|
||
#[inline] | ||
pub fn to_iso(&self) -> Date<Iso> { | ||
self.calendar.as_calendar().date_to_iso(self.inner()) | ||
} | ||
|
||
/// The number of months in the year of this date | ||
#[inline] | ||
pub fn months_in_year(&self) -> u8 { | ||
self.calendar.as_calendar().months_in_year(self.inner()) | ||
} | ||
|
||
/// The number of days in the year of this date | ||
#[inline] | ||
pub fn days_in_year(&self) -> u32 { | ||
self.calendar.as_calendar().days_in_year(self.inner()) | ||
} | ||
|
||
/// The number of days in the month of this date | ||
#[inline] | ||
pub fn days_in_month(&self) -> u8 { | ||
self.calendar.as_calendar().days_in_month(self.inner()) | ||
} | ||
|
||
/// The day of the week for this date | ||
/// | ||
/// Monday is 1, Sunday is 7, according to ISO | ||
#[inline] | ||
pub fn day_of_week(&self) -> u8 { | ||
self.calendar.as_calendar().day_of_week(self.inner()) | ||
} | ||
|
||
/// Add a `duration` to this date, mutating it | ||
#[inline] | ||
pub fn add(&mut self, duration: DateDuration<A::Calendar>) { | ||
self.calendar | ||
.as_calendar() | ||
.offset_date(&mut self.inner, duration) | ||
} | ||
|
||
/// Add a `duration` to this date, returning the new one | ||
#[inline] | ||
pub fn added(mut self, duration: DateDuration<A::Calendar>) -> Self { | ||
self.add(duration); | ||
self | ||
} | ||
|
||
/// Calculating the duration between `other - self` | ||
#[inline] | ||
pub fn until<B: AsCalendar<Calendar = A::Calendar>>( | ||
&self, | ||
other: &Date<B>, | ||
largest_unit: DurationUnit, | ||
smallest_unit: DurationUnit, | ||
) -> DateDuration<A::Calendar> { | ||
self.calendar | ||
.as_calendar() | ||
.until(self.inner(), other.inner(), largest_unit, smallest_unit) | ||
} | ||
|
||
/// Construct a date from raw values for a given calendar. This does not check any | ||
/// invariants for the date and calendar, and should only be called by calendar implementations. | ||
/// | ||
/// Calling this outside of calendar implementations is sound, but calendar implementations are not | ||
/// expected to do anything sensible with such invalid dates. | ||
#[inline] | ||
pub fn from_raw(inner: <A::Calendar as Calendar>::DateInner, calendar: A) -> Self { | ||
Self { inner, calendar } | ||
} | ||
|
||
/// Get the inner date implementation. Should not be called outside of calendar implementations | ||
#[inline] | ||
pub fn inner(&self) -> &<A::Calendar as Calendar>::DateInner { | ||
&self.inner | ||
} | ||
} | ||
|
||
impl<C, A, B> PartialEq<Date<B>> for Date<A> | ||
where | ||
C: Calendar, | ||
A: AsCalendar<Calendar = C>, | ||
B: AsCalendar<Calendar = C>, | ||
{ | ||
fn eq(&self, other: &Date<B>) -> bool { | ||
self.inner.eq(&other.inner) | ||
} | ||
} | ||
|
||
impl<A: AsCalendar> Eq for Date<A> {} | ||
|
||
impl<A: AsCalendar> fmt::Debug for Date<A> | ||
where | ||
<A::Calendar as Calendar>::DateInner: fmt::Debug, | ||
{ | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { | ||
write!( | ||
f, | ||
"Date({:?}, for calendar {})", | ||
self.inner, | ||
A::Calendar::debug_name() | ||
) | ||
} | ||
} | ||
|
||
impl<A: AsCalendar + Clone> Clone for Date<A> { | ||
fn clone(&self) -> Self { | ||
Self { | ||
inner: self.inner.clone(), | ||
calendar: self.calendar.clone(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// This file is part of ICU4X. For terms of use, please see the file | ||
// called LICENSE at the top level of the ICU4X source tree | ||
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
|
||
use crate::Calendar; | ||
use std::fmt; | ||
use std::marker::PhantomData; | ||
|
||
#[derive(Copy, Clone, Eq, PartialEq)] | ||
/// A duration between two dates | ||
pub struct DateDuration<C: Calendar + ?Sized> { | ||
pub years: i32, | ||
pub months: i32, | ||
pub weeks: i32, | ||
pub days: i32, | ||
pub marker: PhantomData<C>, | ||
} | ||
|
||
#[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
pub enum DurationUnit { | ||
Years, | ||
Months, | ||
Weeks, | ||
Days, | ||
} | ||
|
||
impl<C: Calendar + ?Sized> Default for DateDuration<C> { | ||
fn default() -> Self { | ||
Self { | ||
years: 0, | ||
months: 0, | ||
weeks: 0, | ||
days: 0, | ||
marker: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl<C: Calendar + ?Sized> DateDuration<C> { | ||
pub fn new(years: i32, months: i32, weeks: i32, days: i32) -> Self { | ||
DateDuration { | ||
years, | ||
months, | ||
weeks, | ||
days, | ||
marker: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl<C: Calendar> fmt::Debug for DateDuration<C> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { | ||
f.debug_struct("DateDuration") | ||
.field("years", &self.years) | ||
.field("months", &self.months) | ||
.field("weeks", &self.weeks) | ||
.field("days", &self.days) | ||
.finish() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// This file is part of ICU4X. For terms of use, please see the file | ||
// called LICENSE at the top level of the ICU4X source tree | ||
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
|
||
#[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||
pub enum Error { | ||
OutOfRange, | ||
} |
Oops, something went wrong.