1 #pragma once
2 
3 #include <mbgl/util/optional.hpp>
4 
5 #include <string>
6 
7 /*
8     Use LanguageTag to go back and forth between BCP 47 language tags
9     and their component language/script/region.
10 
11     This implementation accepts but will not round-trip additional
12     variant/extension/privateuse/grandfathered information in a BCP 47 tag.
13 
14     Why implement this?
15         Mapbox Style Spec specifies locales with BCP 47
16         Android and Intl.Collator implementations speak BCP 47 out of the box
17         Darwin implementation requires translation to "Language Identifier"
18         We're OK with not supporting extensions, but we want to succesfully
19          parse any valid BCP 47 tag and get out the base language/script/region.
20 
21     Mozilla's version: https://dxr.mozilla.org/mozilla-central/source/intl/locale/MozLocale.cpp
22         Looks like it actually supports a subset of BCP 47.
23         See https://bugzilla.mozilla.org/show_bug.cgi?id=bcp47
24 
25     Chromium is based on ICU version: https://ssl.icu-project.org/apiref/icu4c/uloc_8h.html
26         Getting all the locale information is overkill for us, we just want
27          language/script/region.
28  */
29 
30 namespace mbgl {
31 
32 struct LanguageTag {
33     LanguageTag() = default;
34     LanguageTag(optional<std::string> language_, optional<std::string> script_, optional<std::string> region_);
35 
36     static LanguageTag fromBCP47(const std::string& bcp47Tag);
37     std::string toBCP47() const;
38 
39     optional<std::string> language; // ISO 639
40     optional<std::string> script;   // ISO 15924
41     optional<std::string> region;   // ISO 3316-1 || UN M.49
42 };
43 
44 } // end namespace mbgl
45