From 4547b622d8d29df964fa2914213088b148c498fc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:32 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/icu_locid/src/macros.rs | 191 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 vendor/icu_locid/src/macros.rs (limited to 'vendor/icu_locid/src/macros.rs') diff --git a/vendor/icu_locid/src/macros.rs b/vendor/icu_locid/src/macros.rs new file mode 100644 index 000000000..4537cd403 --- /dev/null +++ b/vendor/icu_locid/src/macros.rs @@ -0,0 +1,191 @@ +// 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 ). + +/// A macro allowing for compile-time construction of valid [`LanguageIdentifier`]s. +/// +/// The macro will perform syntax canonicalization of the tag. +/// +/// # Examples +/// +/// ``` +/// use icu::locid::{langid, LanguageIdentifier}; +/// +/// const DE_AT: LanguageIdentifier = langid!("de_at"); +/// +/// let de_at: LanguageIdentifier = "de_at".parse().unwrap(); +/// +/// assert_eq!(DE_AT, de_at); +/// ``` +/// +/// *Note*: The macro cannot produce language identifiers with more than one variants due to const +/// limitations (see [`Heap Allocations in Constants`]): +/// +/// ```compile_fail,E0080 +/// icu::locid::langid!("und-variant1-variant2"); +/// ``` +/// +/// Use runtime parsing instead: +/// ``` +/// "und-variant1-variant2" +/// .parse::() +/// .unwrap(); +/// ``` +/// +/// [`LanguageIdentifier`]: crate::LanguageIdentifier +/// [`Heap Allocations in Constants`]: https://github.com/rust-lang/const-eval/issues/20 +#[macro_export] +macro_rules! langid { + ($langid:literal) => {{ + const R: $crate::LanguageIdentifier = + match $crate::LanguageIdentifier::try_from_bytes_with_single_variant($langid.as_bytes()) { + Ok((language, script, region, variant)) => $crate::LanguageIdentifier { + language, + script, + region, + variants: match variant { + Some(v) => $crate::subtags::Variants::from_variant(v), + None => $crate::subtags::Variants::new(), + } + }, + #[allow(clippy::panic)] // const context + _ => panic!(concat!("Invalid language code: ", $langid, " . Note langid! macro can only support up to a single variant tag. Use runtime parsing instead.")), + }; + R + }}; +} + +/// A macro allowing for compile-time construction of valid [`Locale`]s. +/// +/// The macro will perform syntax canonicalization of the tag. +/// +/// # Examples +/// +/// ``` +/// use icu::locid::{locale, Locale}; +/// +/// const DE_AT: Locale = locale!("de_at"); +/// +/// let de_at: Locale = "de_at".parse().unwrap(); +/// +/// assert_eq!(DE_AT, de_at); +/// ``` +/// +/// *Note*: The macro cannot produce locales with more than one variant or multiple extensions +/// (only single keyword unicode extension is supported) due to const +/// limitations (see [`Heap Allocations in Constants`]): +/// +/// ```compile_fail,E0080 +/// icu::locid::locale!("sl-IT-rozaj-biske-1994"); +/// ``` +/// Use runtime parsing instead: +/// ``` +/// "sl-IT-rozaj-biske-1994" +/// .parse::() +/// .unwrap(); +/// ``` +/// +/// Locales with multiple keys are not supported +/// ```compile_fail,E0080 +/// icu::locid::locale!("th-TH-u-ca-buddhist-nu-thai"); +/// ``` +/// Use runtime parsing instead: +/// ``` +/// "th-TH-u-ca-buddhist-nu-thai" +/// .parse::() +/// .unwrap(); +/// ``` +/// +/// Locales with attributes are not supported +/// ```compile_fail,E0080 +/// icu::locid::locale!("en-US-u-foobar-ca-buddhist"); +/// ``` +/// Use runtime parsing instead: +/// ``` +/// "en-US-u-foobar-ca-buddhist" +/// .parse::() +/// .unwrap(); +/// ``` +/// +/// Locales with single key but multiple types are not supported +/// ```compile_fail,E0080 +/// icu::locid::locale!("en-US-u-ca-islamic-umalqura"); +/// ``` +/// Use runtime parsing instead: +/// ``` +/// "en-US-u-ca-islamic-umalqura" +/// .parse::() +/// .unwrap(); +/// ``` +/// [`Locale`]: crate::Locale +/// [`Heap Allocations in Constants`]: https://github.com/rust-lang/const-eval/issues/20 +#[macro_export] +macro_rules! locale { + ($locale:literal) => {{ + const R: $crate::Locale = + match $crate::Locale::try_from_bytes_with_single_variant_single_keyword_unicode_extension( + $locale.as_bytes(), + ) { + Ok((language, script, region, variant, keyword)) => $crate::Locale { + id: $crate::LanguageIdentifier { + language, + script, + region, + variants: match variant { + Some(v) => $crate::subtags::Variants::from_variant(v), + None => $crate::subtags::Variants::new(), + }, + }, + extensions: match keyword { + Some(k) => $crate::extensions::Extensions::from_unicode( + $crate::extensions::unicode::Unicode { + keywords: $crate::extensions::unicode::Keywords::new_single( + k.0, + $crate::extensions::unicode::Value::from_tinystr(k.1), + ), + + attributes: $crate::extensions::unicode::Attributes::new(), + }, + ), + None => $crate::extensions::Extensions::new(), + }, + }, + #[allow(clippy::panic)] // const context + _ => panic!(concat!( + "Invalid language code: ", + $locale, + " . Note the locale! macro only supports up to one variant tag; \ + unicode extensions are not supported. Use \ + runtime parsing instead." + )), + }; + R + }}; +} + +#[cfg(test)] +mod test { + use crate::LanguageIdentifier; + use crate::Locale; + + #[test] + fn test_langid_macro_can_parse_langid_with_single_variant() { + const DE_AT_FOOBAR: LanguageIdentifier = langid!("de_at-foobar"); + let de_at_foobar: LanguageIdentifier = "de_at-foobar".parse().unwrap(); + assert_eq!(DE_AT_FOOBAR, de_at_foobar); + } + + #[test] + fn test_locale_macro_can_parse_locale_with_single_variant() { + const DE_AT_FOOBAR: Locale = locale!("de_at-foobar"); + let de_at_foobar: Locale = "de_at-foobar".parse().unwrap(); + assert_eq!(DE_AT_FOOBAR, de_at_foobar); + } + + #[test] + fn test_locale_macro_can_parse_locale_with_single_keyword_unicode_extension() { + const DE_AT_U_CA_FOOBAR: Locale = locale!("de_at-u-ca-foobar"); + let de_at_u_ca_foobar: Locale = "de_at-u-ca-foobar".parse().unwrap(); + assert_eq!(DE_AT_U_CA_FOOBAR, de_at_u_ca_foobar); + } +} -- cgit v1.2.3