locale_settings/codeset.rs
1/*!
2Fetch locale-specific code-set settings.
3
4This module is relatively simple as only a small number of
5settings are defined by POSIX for the code-set category.
6
7*/
8
9use crate::ffi::utils::*;
10use crate::ffi::{___mb_cur_max, CODESET};
11use crate::Category;
12use locale_types::{Locale, LocaleResult};
13
14// ------------------------------------------------------------------------------------------------
15// Public Types
16// ------------------------------------------------------------------------------------------------
17
18/// Settings related to message display.
19#[derive(Debug, Clone, PartialEq)]
20pub struct CodeSetFormat {
21 /// The code set to use when displaying messages in the current locale.
22 /// Note that this does not return standard code set identifiers and so
23 /// this value cannot be used with the `codes::codesets` module.
24 pub code_set: Option<String>,
25 /// The maximum number of bytes needed to represent a single wide
26 /// character in the current locale.
27 pub multibyte_max_bytes: Option<u32>,
28}
29
30// ------------------------------------------------------------------------------------------------
31// Public Functions
32// ------------------------------------------------------------------------------------------------
33
34/// Fetch the code-set settings for the current locale.
35pub fn get_code_set_format() -> CodeSetFormat {
36 let mb_max_bytes = unsafe { ___mb_cur_max() as u32 };
37 CodeSetFormat {
38 code_set: get_nl_string(CODESET),
39 multibyte_max_bytes: Some(mb_max_bytes),
40 }
41}
42
43/// Fetch the code-set rules for a specified `Locale`.
44///
45/// # Arguments
46///
47/// * `locale` - The locale to query.
48/// * `inherit_current` - Whether the specified locale should inherit
49/// from the current locale.
50///
51/// If `inherit_current` is `false` the `locale` specified will be treated
52/// as an entirely new and complete locale when calling the C
53/// [`newlocale`](https://man.openbsd.org/newlocale.3) function. If it is
54/// `true` the `locale` is assumed to be a partially specified one and inherits
55/// any unspecified components from the current locale. For example, if the
56/// current locale is `en_US.UTF-8` and the parameters passed are `_NZ` and
57/// `true` then the resulting locale will be `en_NZ.UTF-8`.
58pub fn get_code_set_format_for_locale(
59 locale: Locale,
60 inherit_current: bool,
61) -> LocaleResult<CodeSetFormat> {
62 get_format_for_locale(
63 Category::CharacterTypes,
64 locale,
65 &get_code_set_format,
66 inherit_current,
67 )
68}
69
70// ------------------------------------------------------------------------------------------------
71// Unit Tests
72// ------------------------------------------------------------------------------------------------
73
74#[cfg(test)]
75mod tests {
76 use crate::codeset::{get_code_set_format, get_code_set_format_for_locale};
77 use crate::locale::{set_locale, Category};
78 use locale_types::Locale;
79 use std::str::FromStr;
80
81 // --------------------------------------------------------------------------------------------
82 #[test]
83 fn test_get_code_set_format() {
84 if set_locale(&Locale::POSIX, &Category::CharacterTypes) {
85 let format = get_code_set_format();
86 println!("{:#?}", format);
87 assert_eq!(format.code_set, Some("US-ASCII".to_string()));
88 assert_eq!(format.multibyte_max_bytes, Some(1));
89 } else {
90 panic!("set_locale returned false");
91 }
92 }
93
94 // --------------------------------------------------------------------------------------------
95 #[test]
96 fn test_get_code_set_format_for_locale() {
97 if set_locale(&Locale::POSIX, &Category::CharacterTypes) {
98 let format = get_code_set_format_for_locale(Locale::from_str("fr_FR").unwrap(), false);
99 println!("{:#?}", format);
100 let format = format.unwrap();
101 assert_eq!(format.code_set, None);
102 assert_eq!(format.multibyte_max_bytes, Some(4));
103 } else {
104 panic!("set_locale returned false");
105 }
106 }
107
108 #[test]
109 fn test_get_code_set_format_for_locale_2() {
110 if set_locale(&Locale::POSIX, &Category::CharacterTypes) {
111 let format =
112 get_code_set_format_for_locale(Locale::from_str("fr_FR.UTF-8").unwrap(), false);
113 println!("{:#?}", format);
114 let format = format.unwrap();
115 assert_eq!(format.code_set, Some("UTF-8".to_string()));
116 assert_eq!(format.multibyte_max_bytes, Some(4));
117 } else {
118 panic!("set_locale returned false");
119 }
120 }
121}