ako 0.0.3

Ako is a Rust crate that offers a practical and human-friendly approach to creating, manipulating, formatting and converting dates, times and timestamps.
Documentation
//! Provides the [`Calendar`] trait which is used to define a **calendar** system.
//!
//! In **Ako**, several types have a type parameter of `Calendar`.
//! This type parameter enables these types to be generic across different calendar systems,
//! allowing for flexible and adaptable time representations.
//!
//! Humans traditionally divide time into components such as years, months, and days.
//! There are
//! multiple calendar systems in common use around the world, including the Gregorian, Julian,
//! and Buddhist calendars.
//! Each of these systems allows people to reference the same moments in
//! time in various culturally specific ways.
//!
//! By default, this module uses the [ISO-8601] calendar, represented by the [`Iso`] type.
//! The
//! ISO-8601 calendar is an internationally accepted way to represent dates and times, and it is
//! widely supported in most libraries and applications that deal with calendar systems.
//! If you
//! are unsure which calendar system to use, the ISO-8601 calendar is probably the best choice.
//!
//! [ISO-8601]: https://en.wikipedia.org/wiki/ISO_8601https://en.wikipedia.org/wiki/ISO_8601
//!

use core::hash::Hash;

use crate::{Date, Month, Year, YearMonth};

pub(crate) mod iso;

pub use iso::Iso;

/// A **calendar** system translates a generic “local timeline”
/// into human-readable units such as years, months, and days.
///
pub trait Calendar: PartialEq + Eq + Hash + Copy + Clone + Sized + Send + Sync + 'static {
    // Date

    /// Obtains a [`Date`] for the `year`, `month`, and `day` on the calendar.
    // TODO: Return ako::Result<_>
    fn date(self, year: i32, month: u8, day: u8) -> crate::Result<Date<Self>>;

    /// Gets the day-of-year of the given [`Date`].
    #[doc(hidden)]
    fn date_from_ordinal(self, year: i32, day: u16) -> crate::Result<Date<Self>>;

    /// Gets the components of the given [`Date`].
    #[doc(hidden)]
    fn date_components(self, days: i32) -> (Year<Self>, Month<Self>, u8);

    /// Gets the day-of-year of the given [`Date`].
    #[doc(hidden)]
    fn date_to_ordinal(self, days: i32) -> (Year<Self>, u16);

    // Year

    /// Obtains a [`Year`] for the `year`.
    fn year(self, year: i32) -> crate::Result<Year<Self>>;

    /// Checks if the `year` is a leap year.
    #[doc(hidden)]
    fn year_is_leap(self, year: i32) -> bool;

    /// Gets the number of days in `year`.
    #[doc(hidden)]
    fn year_days(self, year: i32) -> u16;

    /// Gets the number of months in `year`.
    #[doc(hidden)]
    fn year_months(self, year: i32) -> u8;

    // YearMonth

    /// Obtains a [`YearMonth`] for the `year` and `month`.
    fn year_month(self, year: i32, month: u8) -> crate::Result<YearMonth<Self>>;

    /// Gets the number of days in the `month` of a `year`.
    #[doc(hidden)]
    fn year_month_days(self, year: i32, month: u8) -> u8;
}