Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lint missing docs in icu_datetime #725

Merged
merged 5 commits into from
Aug 31, 2021
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
48 changes: 44 additions & 4 deletions components/datetime/src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,32 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

//! A collection of utilities for representing and working with dates as an input to
//! formatting operations.

use core::convert::TryFrom;
use core::ops::{Add, Sub};
use core::str::FromStr;
use displaydoc::Display;
use icu_locid::Locale;
use tinystr::TinyStr8;

/// A list of possible error outcomes for working with various inputs to DateTime inputs
/// and operations.
#[derive(Display, Debug)]
pub enum DateTimeError {
/// An input could not be parsed.
#[displaydoc("{0}")]
Parse(core::num::ParseIntError),
/// An input overflowed its range.
#[allow(missing_docs)] // TODO(#686) - Add missing docs.
#[displaydoc("{field} must be between 0-{max}")]
Overflow { field: &'static str, max: usize },
#[allow(missing_docs)] // TODO(#686) - Add missing docs.
#[displaydoc("{field} must be between {min}-0")]
/// An input underflowed its range.
Underflow { field: &'static str, min: isize },
/// The time zone offset was invalid.
#[displaydoc("Failed to parse time-zone offset")]
InvalidTimeZoneOffset,
}
Expand Down Expand Up @@ -249,11 +260,18 @@ pub struct Month {
pub code: MonthCode,
}

/// A struct containing various details about the position of the day within a year. It is returned
// by the [`day_of_year_info()`](trait.DateInput.html#tymethod.day_of_year_info) method of the
// [`DateInput`] trait.
#[derive(Clone, Debug, PartialEq)]
pub struct DayOfYearInfo {
/// The current day of the year, 1-based.
pub day_of_year: u32,
/// The number of days in a year.
pub days_in_year: u32,
/// The previous year.
pub prev_year: Year,
/// The next year.
pub next_year: Year,
}

Expand All @@ -270,6 +288,7 @@ pub struct DayOfYearInfo {
/// assert_eq!(7, IsoWeekday::Sunday as usize);
/// ```
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(missing_docs)] // The weekday variants should be self-obvious.
Copy link
Member

Choose a reason for hiding this comment

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

Question

This has a doc comment. Why is the linter saying it's missing?

Copy link
Member Author

Choose a reason for hiding this comment

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

All fields require doc comments. Here the comments wouldn't add any more meaning.

e.g.

/// ...
pub enum IsoWeekday {
    /// This is a Monday!
    Monday = 1,
    ....
}

#[repr(i8)]
pub enum IsoWeekday {
Monday = 1,
Expand Down Expand Up @@ -319,11 +338,13 @@ pub struct WeekOfYear(pub u32);
/// unit is bounded by a range. The traits implemented here will return a Result on
/// whether or not the unit is in range from the given input.
macro_rules! dt_unit {
($name:ident, $value:expr) => {
($name:ident, $value:expr, $docs:expr) => {
#[doc=$docs]
#[derive(Debug, Default, Clone, Copy, PartialEq, Hash)]
pub struct $name(u8);

impl $name {
/// Do not validate the numeric input for this component.
pub const fn new_unchecked(input: u8) -> Self {
Self(input)
}
Expand Down Expand Up @@ -405,17 +426,34 @@ macro_rules! dt_unit {
};
}

dt_unit!(IsoHour, 24);
dt_unit!(
IsoHour,
24,
"An ISO-8601 hour component, for use with the [`IsoTimeInput`]."
);

dt_unit!(IsoMinute, 60);
dt_unit!(
IsoMinute,
60,
"An ISO-8601 minute component, for use with the [`IsoTimeInput`]."
);

dt_unit!(IsoSecond, 61);
dt_unit!(
IsoSecond,
61,
"An ISO-8601 second component, for use with the [`IsoTimeInput`]."
);

// TODO(#485): Improve FractionalSecond.
/// A placeholder for fractional seconds support. See [Issue #485](https://github.com/unicode-org/icu4x/issues/485)
/// for tracking the support of this feature.
#[derive(Clone, Debug, PartialEq)]
pub enum FractionalSecond {
/// The millisecond component of the fractional second.
Millisecond(u16),
/// The microsecond component of the fractional second.
Microsecond(u32),
/// The nanosecond component of the fractional second.
Nanosecond(u32),
}

Expand All @@ -424,6 +462,8 @@ pub enum FractionalSecond {
pub struct GmtOffset(i32);

impl GmtOffset {
/// Attempt to create a [`GmtOffset`] from a seconds input. It returns an error when the seconds
/// overflows or underflows.
pub fn try_new(seconds: i32) -> Result<Self, DateTimeError> {
// Valid range is from GMT-12 to GMT+14 in seconds.
if seconds < -(12 * 60 * 60) {
Expand Down
3 changes: 3 additions & 0 deletions components/datetime/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

//! The collection of code that is needed for handling formatting operations for DateTimes.
//! Central to this is the [`DateTimeFormat`].

use crate::{
format::datetime,
options::DateTimeFormatOptions,
Expand Down
3 changes: 3 additions & 0 deletions components/datetime/src/format/zoned_datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

//! A collection of code for formatting DateTimes with time zones.

use crate::date::{LocalizedDateTimeInput, ZonedDateTimeInputWithLocale};
use crate::error::DateTimeFormatError as Error;
use crate::fields::{self, FieldSymbol};
Expand All @@ -13,6 +15,7 @@ use writeable::Writeable;
use super::datetime;
use super::time_zone;

#[allow(missing_docs)] // TODO(#686) - Add missing docs.
pub struct FormattedZonedDateTime<'l, 'data, T>
where
T: ZonedDateTimeInput,
Expand Down
4 changes: 4 additions & 0 deletions components/datetime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

#![warn(missing_docs)]

//! `icu_datetime` is one of the [`ICU4X`] components.
//!
//! This API provides necessary functionality for formatting date and time to user readable textual representation.
Expand Down Expand Up @@ -88,7 +90,9 @@ pub mod provider;
#[doc(hidden)]
pub mod skeleton;
// TODO(#622) make the time_zone module public once TimeZoneFormat is public.
#[allow(missing_docs)] // TODO(#686) - Add missing docs.
pub(crate) mod time_zone;
#[allow(missing_docs)] // TODO(#686) - Add missing docs.
pub mod zoned_datetime;

pub use datetime::DateTimeFormat;
Expand Down
8 changes: 8 additions & 0 deletions components/datetime/src/mock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

//! A collection of temporary structs and utilities to input data for tests, benchmarks,
//! and examples.

/// Temporary DateTime input utilities.
pub mod datetime;

/// Temporary time zone input utilities.
pub mod time_zone;

/// Temporary zoned DateTime input utilities.
pub mod zoned_datetime;
27 changes: 27 additions & 0 deletions components/datetime/src/options/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,28 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Bag {
/// Include the era, such as "AD" or "CE".
pub era: Option<Text>,
/// Include the year, such as "1970" or "70".
pub year: Option<Numeric>,
/// Include the month, such as "April" or "Apr".
pub month: Option<Month>,
/// Include the day, such as "07" or "7".
pub day: Option<Numeric>,
/// Include the weekday, such as "Wednesday" or "Wed".
pub weekday: Option<Text>,

/// Include the hour such as "2" or "14".
pub hour: Option<Numeric>,
/// Include the minute such as "3" or "03".
pub minute: Option<Numeric>,
/// Include the second such as "3" or "03".
pub second: Option<Numeric>,

/// Include the time zone, such as "GMT+05:00".
pub time_zone_name: Option<TimeZoneName>,

/// Adjust the preferences for the date, such as setting the hour cycle.
pub preferences: Option<preferences::Bag>,
}

Expand Down Expand Up @@ -303,46 +313,63 @@ impl Default for Bag {
}
}

/// A numeric component for the `components::`[`Bag`]. It is used for the year, day, hour, minute,
/// and second.
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Numeric {
/// Display the numeric value. For instance in a year this would be "1970".
#[cfg_attr(feature = "serde", serde(rename = "numeric"))]
Numeric,
/// Display the two digit value. For instance in a year this would be "70".
#[cfg_attr(feature = "serde", serde(rename = "two-digit"))]
TwoDigit,
}

/// A text component for the `components::`[`Bag`]. It is used for the era and weekday.
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Text {
/// Display the long form of the text, such as "Wednesday" for the weekday.
#[cfg_attr(feature = "serde", serde(rename = "long"))]
Long,
/// Display the short form of the text, such as "Wed" for the weekday.
#[cfg_attr(feature = "serde", serde(rename = "short"))]
Short,
/// Display the narrow form of the text, such as "W" for the weekday.
#[cfg_attr(feature = "serde", serde(rename = "narrow"))]
Narrow,
}

/// Options for displaying a Month for the `components::`[`Bag`].
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Month {
/// The numeric value of the month, such as "4".
#[cfg_attr(feature = "serde", serde(rename = "numeric"))]
Numeric,
/// The two-digit value of the month, such as "04".
#[cfg_attr(feature = "serde", serde(rename = "two-digit"))]
TwoDigit,
/// The two-digit value of the month, such as "April".
#[cfg_attr(feature = "serde", serde(rename = "long"))]
Long,
/// The short value of the month, such as "Apr".
#[cfg_attr(feature = "serde", serde(rename = "short"))]
Short,
/// The narrow value of the month, such as "A".
#[cfg_attr(feature = "serde", serde(rename = "narrow"))]
Narrow,
}

/// Options for displaying a time zone for the `components::`[`Bag`].
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TimeZoneName {
#[allow(missing_docs)] // TODO(#686) - Add missing docs.
#[cfg_attr(feature = "serde", serde(rename = "long"))]
Long,
#[allow(missing_docs)] // TODO(#686) - Add missing docs.
#[cfg_attr(feature = "serde", serde(rename = "short"))]
Short,
}
Expand Down
3 changes: 3 additions & 0 deletions components/datetime/src/options/length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Bag {
/// Configure the date part of the datetime.
pub date: Option<Date>,
/// Configure the time part of the datetime.
pub time: Option<Time>,
/// Configure the preferences for the datetime, such as the hour cycle.
pub preferences: Option<preferences::Bag>,
}

Expand Down
4 changes: 4 additions & 0 deletions components/datetime/src/options/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Bag {
/// The hour cycle can be adjusts according to user preferences, for instance at the OS-level.
/// That preference can be applied here to change the hour cycle from the default for the
/// given locale.
#[cfg_attr(feature = "serde", serde(rename = "hourCycle"))]
pub hour_cycle: Option<HourCycle>,
}
Expand Down Expand Up @@ -102,6 +105,7 @@ pub enum HourCycle {
}

impl HourCycle {
/// Convert the HourCycle preference to a field.
pub fn field(self) -> fields::Hour {
match self {
Self::H11 => fields::Hour::H11,
Expand Down
2 changes: 1 addition & 1 deletion components/datetime/src/pattern/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::fields;
use displaydoc::Display;

/// These strings follow the recommendations for the serde::de::Unexpected::Other type.
/// https://docs.serde.rs/serde/de/enum.Unexpected.html#variant.Other
/// <https://docs.serde.rs/serde/de/enum.Unexpected.html#variant.Other>
///
/// Serde will generate an error such as:
/// "invalid value: unclosed literal in pattern, expected a valid UTS 35 pattern string at line 1 column 12"
Expand Down
2 changes: 2 additions & 0 deletions components/datetime/src/provider/gregory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

#![allow(missing_docs)] // TODO(#686) - Add missing docs.

use crate::pattern;
use alloc::borrow::Cow;
use icu_provider::yoke::{self, *};
Expand Down
27 changes: 27 additions & 0 deletions components/datetime/src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,51 @@
//!
//! Read more about data providers: [`icu_provider`]

#[cfg(doc)]
use icu_provider::prelude::ResourceKey;

/// Data providers for the Gregorian Calendar.
pub mod gregory;

pub(crate) mod helpers;

/// Data providers for time zones.
pub mod time_zones;

/// A collection of [`ResourceKey`] structs for DateTime providers.
pub mod key {
#[cfg(doc)]
use crate::provider::{gregory, time_zones};

use icu_provider::{resource_key, ResourceKey};

/// A [`ResourceKey`] to [`gregory::DatePatternsV1`].
pub const GREGORY_DATE_PATTERNS_V1: ResourceKey =
resource_key!(DateTime, "gregory_patterns", 1);

/// A [`ResourceKey`] to [`gregory::DateSymbolsV1`]
pub const GREGORY_DATE_SYMBOLS_V1: ResourceKey = resource_key!(DateTime, "gregory_symbols", 1);

/// A [`ResourceKey`] to [`time_zones::TimeZoneFormatsV1`].
pub const TIMEZONE_FORMATS_V1: ResourceKey = resource_key!(TimeZone, "formats", 1);

/// A [`ResourceKey`] to [`time_zones::ExemplarCitiesV1`].
pub const TIMEZONE_EXEMPLAR_CITIES_V1: ResourceKey =
resource_key!(TimeZone, "exemplar_cities", 1);

/// A [`ResourceKey`] to [`time_zones::MetaZoneGenericNamesLongV1`].
pub const TIMEZONE_GENERIC_NAMES_LONG_V1: ResourceKey =
resource_key!(TimeZone, "generic_long", 1);

/// A [`ResourceKey`] to [`time_zones::MetaZoneGenericNamesShortV1`].
pub const TIMEZONE_GENERIC_NAMES_SHORT_V1: ResourceKey =
resource_key!(TimeZone, "generic_short", 1);

/// A [`ResourceKey`] to [`time_zones::MetaZoneSpecificNamesLongV1`].
pub const TIMEZONE_SPECIFIC_NAMES_LONG_V1: ResourceKey =
resource_key!(TimeZone, "specific_long", 1);

/// A [`ResourceKey`] to [`time_zones::MetaZoneSpecificNamesShortV1`].
pub const TIMEZONE_SPECIFIC_NAMES_SHORT_V1: ResourceKey =
resource_key!(TimeZone, "specific_short", 1);
}
2 changes: 2 additions & 0 deletions components/datetime/src/provider/time_zones.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use tinystr::TinyStr8;
macro_rules! map_access {
($outer: ty[$key: ty] => $inner: ty: $lt: lifetime) => {
impl<$lt> $outer {
/// Get the data from the key.
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&$inner>
where
Q: Ord,
Expand All @@ -20,6 +21,7 @@ macro_rules! map_access {
self.0.get(key)
}

/// Check if the underlying data is empty.
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
Expand Down
Loading