relibc/header/monetary/
mod.rs1use alloc::string::{String, ToString};
9use core::str;
10
11use libm::{fabs, pow, round, trunc};
12
13extern crate alloc;
14
15mod strfmon;
16#[repr(C)]
17struct LocaleMonetaryInfo {
18 int_curr_symbol: &'static str,
19 currency_symbol: &'static str,
20 mon_decimal_point: &'static str,
21 mon_thousands_sep: &'static str,
22 mon_grouping: &'static [u8],
23 positive_sign: &'static str,
24 negative_sign: &'static str,
25 int_frac_digits: u8,
26 frac_digits: u8,
27 p_cs_precedes: bool,
28 p_sep_by_space: bool,
29 p_sign_posn: u8,
30 n_cs_precedes: bool,
31 n_sep_by_space: bool,
32 n_sign_posn: u8,
33}
34
35const DEFAULT_MONETARY: LocaleMonetaryInfo = LocaleMonetaryInfo {
36 int_curr_symbol: "USD ",
37 currency_symbol: "$",
38 mon_decimal_point: ".",
39 mon_thousands_sep: ",",
40 mon_grouping: &[3, 3],
41 positive_sign: "",
42 negative_sign: "-",
43 int_frac_digits: 2,
44 frac_digits: 2,
45 p_cs_precedes: true,
46 p_sep_by_space: false,
47 p_sign_posn: 1,
48 n_cs_precedes: true,
49 n_sep_by_space: false,
50 n_sign_posn: 1,
51};
52
53#[derive(Default)]
54struct FormatFlags {
55 left_justify: bool,
56 force_sign: bool,
57 space_sign: bool,
58 use_parens: bool,
59 suppress_symbol: bool,
60 field_width: Option<usize>,
61 left_precision: Option<usize>,
62 right_precision: Option<usize>,
63 international: bool,
64}
65
66fn apply_grouping(int_str: &str, monetary: &LocaleMonetaryInfo) -> String {
68 let mut grouped = String::with_capacity(int_str.len() * 2);
69 let mut group_idx = 0;
70 let current_grouping = &monetary.mon_grouping;
71 let separator = monetary.mon_thousands_sep;
72
73 for (count, c) in int_str.chars().enumerate() {
74 if count > 0 {
75 let current_group = current_grouping[group_idx.min(current_grouping.len() - 1)];
76 if current_group > 0 && (count as u8).is_multiple_of(current_group) {
77 grouped.push_str(separator);
78 if group_idx + 1 < current_grouping.len() {
79 group_idx += 1;
80 }
81 }
82 }
83 grouped.push(c);
84 }
85
86 grouped
87}
88
89fn format_value_parts(value: f64, frac_digits: usize) -> Option<(String, i64)> {
91 let abs_value = fabs(value);
92 if abs_value > (i64::MAX as f64) {
93 return None;
95 }
96
97 let int_part = trunc(abs_value) as i64;
98 let scale = pow(10.0, frac_digits as f64);
99 let frac_part = round((abs_value - int_part as f64) * scale) as i64;
100
101 Some((int_part.to_string(), frac_part))
102}