1//! `unic-langid` is a core API for parsing, manipulating, and serializing Unicode Language
2//! Identifiers.
3//!
4//! The crate provides algorithms for parsing a string into a well-formed language identifier
5//! as defined by [`UTS #35: Unicode LDML 3.1 Unicode Language Identifier`].
6//!
7//! # Examples
8//!
9//! ```
10//! use unic_langid::LanguageIdentifier;
11//! use unic_langid::subtags::{Language, Script, Region};
12//!
13//! let mut li: LanguageIdentifier = "en-US".parse()
14//! .expect("Parsing failed.");
15//!
16//! let lang: Language = "en".parse().expect("Parsing failed.");
17//! let region: Region = "US".parse().expect("Parsing failed.");
18//! assert_eq!(li.language, lang);
19//! assert_eq!(li.script, None);
20//! assert_eq!(li.region, Some(region));
21//! assert_eq!(li.variants().len(), 0);
22//!
23//! let region: Region = "GB".parse().expect("Parsing failed.");
24//! li.region = Some(region);
25//!
26//! assert_eq!(li.to_string(), "en-GB");
27//! ```
28//!
29//! For more details, see [`LanguageIdentifier`].
30//!
31//! # Optional features
32//!
33//! ## `langid!`, `langids!`, and `langid_slice!` macros
34//!
35//! If `feature = "macros"` is selected, the crate provides a procedural macro
36//! which allows to construct build-time well-formed language identifiers with zero-cost at runtime.
37//!
38//! ``` ignore
39//! use unic_langid::{langid, langid_slice, langids, lang, region, script, variant, LanguageIdentifier};
40//! use unic_langid::subtags::{Language, Script, Region, Variant};
41//! use std::str::FromStr;
42//!
43//! let es_ar = langid!("es-AR");
44//! let en_us = langid!("en-US");
45//!
46//! assert_eq!(&es_ar.to_string(), "es-AR");
47//! assert_eq!(&en_us.to_string(), "en-US");
48//!
49//! let lang_ids = langids!("es-AR", "en-US", "de");
50//!
51//! assert_eq!(lang_ids[0], "es-AR");
52//! assert_eq!(lang_ids[1], "en-US");
53//! assert_eq!(lang_ids[2], "de");
54//!
55//! const LANGUAGES: &[LanguageIdentifier] = langid_slice!["en-GB", "fr"];
56//!
57//! assert_eq!(lang!("pl"), "pl");
58//! assert_eq!(lang!("pl"), Language::from_str("pl").unwrap());
59//!
60//! assert_eq!(script!("latn"), "Latn");
61//! assert_eq!(script!("latn"), Script::from_str("Latn").unwrap());
62//!
63//! assert_eq!(region!("us"), "US");
64//! assert_eq!(region!("us"), Region::from_str("us").unwrap());
65//!
66//! assert_eq!(variant!("macos"), "macos");
67//! assert_eq!(variant!("macos"), Variant::from_str("macos").unwrap());
68//! ```
69//!
70//! The macros produce instances of `LanguageIdentifier` the same way as parsing from `&str` does,
71//! but since the parsing is performed at build time, it doesn't need a `Result`.
72//!
73//! At the moment `langid!` can also be used for const variables, but only if no variants are used.
74//!
75//! The macros are optional to reduce the dependency chain and compilation time of `unic-langid`.
76//!
77//! ## Likely Subtags
78//!
79//! If `feature = "likelysubtags"` is selected, the `LanguageIdentifier` gains two more methods:
80//!
81//! * add_likely_subtags
82//! * remove_likely_subtags
83//!
84//! Both of them operate in place updating the existing `LanguageIdentifier` by either extending
85//! subtags to most likely values, or removing the subtags that are not needed.
86//!
87//! Both methods return a `bool` that indicates if the identifier has been modified.
88//!
89//! ``` ignore
90//! use unic_langid::LanuageIdentifier;
91//!
92//! let mut li: LanguageIdentifier = "fr-FR".parse()
93//! .expect("Parsing failed.");
94//!
95//! assert_eq!(li.add_likely_subtags(), true);
96//! assert_eq!(li, "fr-Latn-FR");
97//!
98//! assert_eq!(li.remove_likely_subtags(), true);
99//! assert_eq!(li, "fr");
100//! ```
101//!
102//! The feature is optional because it increases the binary size of the library by including
103//! a data table for CLDR likelySubtags.
104//!
105//! [`UTS #35: Unicode LDML 3.1 Unicode Language Identifier`]: https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier
106//! [`LanguageIdentifier`]: ./struct.LanguageIdentifier.html
107
108pub use unic_langid_impl::*;
109
110#[cfg(feature = "unic-langid-macros")]
111pub use unic_langid_macros::{lang, langid, region, script, variant};
112
113#[cfg(feature = "unic-langid-macros")]
114#[macro_export]
115macro_rules! langids {
116 ( $($langid:expr),* ) => {
117 vec![$(
118 $crate::langid!($langid),
119 )*]
120 };
121 ( $($langid:expr,)* ) => {
122 $crate::langids![$($langid),*]
123 };
124}
125#[cfg(feature = "unic-langid-macros")]
126#[macro_export]
127macro_rules! langid_slice {
128 ( $($langid:expr),* ) => {
129 &[$(
130 $crate::langid!($langid),
131 )*]
132 };
133 ( $($langid:expr,)* ) => {
134 $crate::langid_slice![$($langid),*]
135 };
136}
137