1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
// 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 ).
//! 🚧 \[Experimental\] Types to hold user preferences to configure a DateTimeFormatter.
//!
//! ✨ *Enabled with the `experimental` Cargo feature.*
//!
//! Preferences is a bag of options to be associated with either [`length::Bag`] or [`components::Bag`]
//! which provides information on user preferences that can affect the result of the formatting.
//!
//! [`length::Bag`]: crate::options::length::Bag
//! [`components::Bag`]: crate::options::components::Bag
//!
//! <div class="stab unstable">
//! 🚧 This code is experimental; it may change at any time, in breaking or non-breaking ways,
//! including in SemVer minor releases. It can be enabled with the `experimental` Cargo feature
//! of the icu meta-crate. Use with caution.
//! <a href="https://github.com/unicode-org/icu4x/issues/1317">#1317</a>
//! </div>
//!
//! # Unicode Extensions
//! User preferences will often be stored as part of the [`Locale`] identified as `Unicode Extensions`, but
//! for scenarios where the application stores information about user preferences they can be also provided via
//! this bag (and if they are, they will take precedence over unicode extensions from the locale).
//!
//! [`Locale`]: icu_locale_core::Locale
//!
//! # Examples
//!
//! ```
//! use icu::datetime::options::preferences;
//!
//! let prefs = preferences::Bag::from_hour_cycle(preferences::HourCycle::H23);
//! ```
use crate::fields;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use icu_locale_core::{
extensions::unicode::Value,
subtags::{subtag, Subtag},
};
/// Stores user preferences which may affect the result of date and time formatting.
///
/// <div class="stab unstable">
/// 🚧 This code is experimental; it may change at any time, in breaking or non-breaking ways,
/// including in SemVer minor releases. It can be enabled with the `experimental` Cargo feature
/// of the icu meta-crate. Use with caution.
/// <a href="https://github.com/unicode-org/icu4x/issues/1317">#1317</a>
/// </div>
///
/// # Examples
///
/// ```
/// use icu::datetime::options::preferences;
///
/// let prefs = preferences::Bag::from_hour_cycle(preferences::HourCycle::H23);
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[non_exhaustive]
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>,
}
impl Bag {
/// Construct a [`Bag`] with a given [`HourCycle`]
#[cfg(feature = "datagen")]
pub fn from_hour_cycle(h: HourCycle) -> Self {
Self {
hour_cycle: Some(h),
}
}
}
/// A user preference for adjusting how the hour component is displayed.
///
/// <div class="stab unstable">
/// 🚧 This code is experimental; it may change at any time, in breaking or non-breaking ways,
/// including in SemVer minor releases. It can be enabled with the `experimental` Cargo feature
/// of the icu meta-crate. Use with caution.
/// <a href="https://github.com/unicode-org/icu4x/issues/1317">#1317</a>
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::exhaustive_enums)] // this type is stable
pub enum HourCycle {
/// Hour is formatted to be in range 1-24 where midnight is 24:00.
///
/// # Examples
///
/// ```
/// "24:12";
/// "8:23";
/// "19:00";
/// "23:21";
/// ```
#[cfg_attr(feature = "serde", serde(rename = "h24"))]
H24,
/// Hour is formatted to be in range 0-23 where midnight is 00:00.
///
/// # Examples
///
/// ```
/// "0:12";
/// "8:23";
/// "19:00";
/// "23:21";
/// ```
#[cfg_attr(feature = "serde", serde(rename = "h23"))]
H23,
/// Hour is formatted to be in range 1-12 where midnight is 12:00.
///
/// # Examples
///
/// ```
/// "1:12";
/// "8:23";
/// "7:00";
/// "11:21";
/// ```
#[cfg_attr(feature = "serde", serde(rename = "h12"))]
H12,
/// Hour is formatted to be in range 0-11 where midnight is 00:00.
///
/// # Examples
///
/// ```
/// "0:12";
/// "8:23";
/// "7:00";
/// "11:21";
/// ```
#[cfg_attr(feature = "serde", serde(rename = "h11"))]
H11,
}
impl HourCycle {
/// Convert the HourCycle preference to a field.
pub fn field(self) -> fields::Hour {
match self {
Self::H11 => fields::Hour::H11,
Self::H12 => fields::Hour::H12,
Self::H23 => fields::Hour::H23,
Self::H24 => fields::Hour::H24,
}
}
pub(crate) fn from_locale_value(value: &Value) -> Option<Self> {
const H11: Subtag = subtag!("h11");
const H12: Subtag = subtag!("h12");
const H23: Subtag = subtag!("h23");
const H24: Subtag = subtag!("h24");
match value.as_single_subtag() {
Some(&H11) => Some(HourCycle::H11),
Some(&H12) => Some(HourCycle::H12),
Some(&H23) => Some(HourCycle::H23),
Some(&H24) => Some(HourCycle::H24),
_ => None,
}
}
}