locale_settings/
lib.rs

1/*!
2An interface to all manner of locale-related information.
3
4This crate provides a higher-level interface to locale settings accessed via POSIX (see
5[ISO/IEC 15897](https://www.iso.org/standard/50707.html) operating system
6functions. These are under the module
7[`simple_locale::settings`](settings/index.html).
8
9This crate uses bindgen for the creation of operating system bindings to the
10`langinfo`, `localcharset`, `locale`, and `xlocale` headers. Another
11crate () does something similar, however...
12
13## Example - Settings
14
15In the following example we have a naïve implementation of a currency formatter.
16To format a US dollar amount correctly we first set the current locale for the
17`Currency` [`Category`](settings/locale/enum.Category.html) and then call the
18[`get_currency_format`](settings/currency/fn.get_currency_format.html). From this we use
19only the simplest of the formatting options to display our currency amount.
20
21```
22use std::str::FromStr;
23use locale_types::{Locale, LocaleString};
24use locale_settings::locale::{Category, set_locale};
25use locale_settings::currency::get_currency_format;
26
27let amount: f64 = 5.909;
28let en_us = LocaleString::from_str("en_US.UTF-8").unwrap();
29
30if set_locale(&Locale::String(en_us), &Category::Currency) {
31    let format = get_currency_format();
32    let local = format.local_format.unwrap();
33    println!(
34        "{2}{0}{3}{1:.4$}",
35        amount.trunc(),
36        amount.fract(),
37        local.currency_symbol,
38        format.number_format.decimal_separator,
39        local.decimal_precision
40    );
41}
42
43```
44
45## FFI Bindings
46
47As mentioned above, this crate depends on FFI bindings to POSIX locale
48functions, and there are O/S differences that make this a pain. The script
49[`create-bindings.sh`](https://github.com/johnstonskj/simple-locale/blob/master/create-bindings.sh)
50is used to generate these bindings (using cargo bindgen) in such a way that
51different O/S bindings can be built effectively.
52
53Typically we treat each of the categories defined by POSIX in `locale.h` as
54modules. The categories are show in the table below.
55
56| POSIX Category | Module     | Function(s)                                  |
57|----------------|------------|----------------------------------------------|
58| `LC_COLLATE`   | N/A        | |
59| `LC_CTYPE`     | [`codeset`](codeset/index.html) | `get_code_set_format`, `get_code_set_format_for_locale` |
60| `LC_MESSAGES`  | [`messages`](messages/index.html) | `get_message_format`, `get_message_format_for_locale` |
61| `LC_MONETARY`  | [`currency`](currency/index.html) | `get_currency_format`, `get_currency_format_for_locale` |
62| `LC_NUMERIC`   | [`numeric`](numeric/index.html) | `get_numeric_format`, `get_numeric_format_for_locale` |
63| `LC_TIME`      | [`time`](time/index.html) | `get_date_time_format`, `get_date_time_format_for_locale`, `get_calendar_names`, `get_calendar_names_for_locale` |
64
65> Note: the POSIX category `LC_COLLATE` is not mapped to
66> modules as there are no calls to retrieve specific information.
67
68For each module there is _at least_ a matching pair of functions, one which takes
69zero parameters and returns the current locale settings, and one which takes
70two parameters and allows the retrieval of settings from another locale. The first
71of these parameters is a [`Locale`](../locale/enum.Locale.html) enum that denotes
72the locale to query, and the second parameter is a boolean `inherit_current` that
73determines how the specified locale should be interpreted.
74
75Additionally, the module [`locale`](locale/index.html) has the necessary functions
76to get and set the locale either for an individual category or for all. This modules
77provides implementations that use the C API directly as well as an implementation
78that uses standard environment variables.
79
80## Relationship to the POSIX API
81
82The POSIX locale API is spread across a number of functions including
83[`localeconv`](https://man.openbsd.org/localeconv.3),
84[`nl_langinfo`](https://man.openbsd.org/nl_langinfo.3), and
85[`setlocale`](https://man.openbsd.org/setlocale.3). Also, the
86different categories of data is mixed up in common structures. The intent
87of this crate is to invert this abstraction, to group together data by common
88category regardless of the underlying API being used.
89
90Those functions in the table above that end in `_for_locale` use the `xlocale`
91extended API, specifically
92[`newlocale`](https://man.openbsd.org/newlocale.3),
93[`uselocale`](https://man.openbsd.org/uselocale.3), and
94[`freelocale`](https://man.openbsd.org/freelocale.3) to obtain the settings
95for a locale other than the current.
96*/
97
98#[macro_use]
99extern crate log;
100extern crate locale_types;
101extern crate regex;
102
103// ------------------------------------------------------------------------------------------------
104// Public Modules
105// ------------------------------------------------------------------------------------------------
106
107pub mod locale;
108pub use locale::Category;
109
110pub mod codeset;
111
112pub mod currency;
113
114pub mod messages;
115
116pub mod numeric;
117
118pub mod time;
119
120// ------------------------------------------------------------------------------------------------
121// Internal Modules
122// ------------------------------------------------------------------------------------------------
123
124mod ffi;