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 170 171 172
/*! An interface to all manner of locale-related information. This crate provides a higher-level interface to a number of locale-related sources, in three areas: 1. Locale-related codes/identifiers and any standards-based information concerning them. For example, ISO-396 language identifiers, or ISO-3166 country identifiers. These are under the module [`simple_locale::codes`](codes/index.html). 1. Locale settings, usually accessed via POSIX (see [ISO/IEC 15897](https://www.iso.org/standard/50707.html) operating system functions. These are under the module [`simple_locale::settings`](settings/index.html). 1. A [`Locale`](locale/enum.Locale.html) enumeration, and a [`LocaleString`](string/struct.LocaleString.html) structure are provided that may be used to parse and construct locale identifiers in a standards-conformant manner. This crate uses bindgen for the creation of operating system bindings to the `langinfo`, `localcharset`, `locale`, and `xlocale` headers. Another crate () does something similar, however... ## Example - Codes The following example demonstrates some of the components of the crate, at least some reasonable use cases. 1. Construct a _strict_ locale string where identifiers are checked against known standard codes where possible. 1. Lookup the ISO-3166 data for the country (in the [`CountryInfo`](codes/country/struct.CountryInfo.html) struct) identified by the ISO-3166, part 2, 3-character identifier. 1. The data fromn the last call contains one or more regions (in the [`RegionInfo`](/codes/region/struct.RegionInfo.html) struct), determine the countries name from the `country_code`. 1. Now we have the country name we can lookup the details of the currencies (in, the [`CurrencyInfo`](CurrencyInfo) struct). ``` use simple_locale::LocaleString; use simple_locale::codes::{country, currency, region}; let locale = LocaleString::new_strict("en".to_string()) .with_territory("US".to_string()) .with_code_set("UTF-8".to_string()) .with_modifier("collation=pinyin;currency=CNY".to_string()); println!("{}", locale); let mexico = country::lookup("MEX").unwrap(); println!("{:?}", mexico); let mexico_region = region::lookup(mexico.country_code).unwrap(); println!("{:?}", mexico_region); let currencies = currency::currencies_for_country_name(mexico_region.name.as_str()); println!("{:?}", currencies); ``` ## Example - Settings In the following example we have a naïve implementation of a currency formatter. To format a US dollar amount correctly we first set the current locale for the `Currency` [`Category`](settings/locale/enum.Category.html) and then call the [`get_currency_format`](settings/currency/fn.get_currency_format.html). From this we use only the simplest of the formatting options to display our currency amount. ``` use std::str::FromStr; use simple_locale::{Locale, LocaleString}; use simple_locale::settings::locale::{Category, set_locale}; use simple_locale::settings::currency::get_currency_format; let amount: f64 = 5.909; let en_us = LocaleString::from_str("en_US.UTF-8").unwrap(); if set_locale(&Locale::String(en_us), &Category::Currency) { let format = get_currency_format(); let local = format.local_format.unwrap(); println!( "{2}{0}{3}{1:.4$}", amount.trunc(), amount.fract(), local.currency_symbol, format.number_format.decimal_separator, local.decimal_precision ); } ``` ## FFI Bindings As mentioned above, this crate depends on FFI bindings to POSIX locale functions, and there are O/S differences that make this a pain. The script [`create-bindings.sh`](https://github.com/johnstonskj/simple-locale/blob/master/create-bindings.sh) is used to generate these bindings (using cargo bindgen) in such a way that different O/S bindings can be built effectively. ## JSON Data Files The script [`create-data-modules`](https://github.com/johnstonskj/simple-locale/blob/master/create-data-modules.sh) on the other hand is used to process files downloaded, or scraped, from standards web sites to create data used by the library. This data is generated as JSON files in the `src/codes/data` folder and read as a part of the build for `codes` modules using the Rust `include!` macro. Currently data is generated for the following standards: * ISO 639 _Codes for the representation of names of languages_; Parts 1-4, 2-character and 3-character codes supported. * ISO 3166 _Codes for the representation of names of countries and their subdivisions_; Part 1, 2-character codes, only. * ISO 4217 _Codes for the representation of currencies_; alphabetic and numeric codes supported. * ISO 15924 _Codes for the representation of names of scripts_; alphabetic and numeric codes supported. Each folder under `src-data` represents a single standard, which may generate one or more data sets. Each directory will contain a Python script, `generate.py` which is called by the top-level script to create the JSON in the correct location. Each should also contain a README that includes attribution for any data retrieved to make this possible. */ #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; extern crate regex; // ------------------------------------------------------------------------------------------------ // Public Types // ------------------------------------------------------------------------------------------------ /// Common error type for functions in this crate. #[derive(Debug)] pub enum LocaleError { /// The provided locale string was badly formatted InvalidLocaleString, /// The provided locale was unknown UnknownLocale, /// Locale category not set/or supported UnsetCategory, /// Operating system could not set the specified locale OSError, /// The operation you tried to perform was not supported. Unsupported, } /// Common result type for functions in this crate. pub type LocaleResult<T> = Result<T, LocaleError>; // ------------------------------------------------------------------------------------------------ // Public Modules // ------------------------------------------------------------------------------------------------ pub mod codes; pub mod string; pub use string::LocaleString; pub mod locale; pub use locale::Locale; pub mod settings; // ------------------------------------------------------------------------------------------------ // Internal Modules // ------------------------------------------------------------------------------------------------ mod ffi;