ffi.rs (4944B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use crate::builtins::FluentDateTimeOptions; 6 use fluent::types::FluentNumberCurrencyDisplayStyle; 7 use fluent::types::FluentNumberOptions; 8 use fluent::types::FluentNumberStyle; 9 use nsstring::nsCString; 10 11 pub enum RawNumberFormatter {} 12 13 #[repr(C)] 14 pub enum FluentNumberStyleRaw { 15 Decimal, 16 Currency, 17 Percent, 18 } 19 20 impl From<FluentNumberStyle> for FluentNumberStyleRaw { 21 fn from(input: FluentNumberStyle) -> Self { 22 match input { 23 FluentNumberStyle::Decimal => Self::Decimal, 24 FluentNumberStyle::Currency => Self::Currency, 25 FluentNumberStyle::Percent => Self::Percent, 26 } 27 } 28 } 29 30 #[repr(C)] 31 #[derive(Clone, Copy)] 32 pub enum FluentNumberCurrencyDisplayStyleRaw { 33 Symbol, 34 Code, 35 Name, 36 } 37 38 impl From<FluentNumberCurrencyDisplayStyle> for FluentNumberCurrencyDisplayStyleRaw { 39 fn from(input: FluentNumberCurrencyDisplayStyle) -> Self { 40 match input { 41 FluentNumberCurrencyDisplayStyle::Symbol => Self::Symbol, 42 FluentNumberCurrencyDisplayStyle::Code => Self::Code, 43 FluentNumberCurrencyDisplayStyle::Name => Self::Name, 44 } 45 } 46 } 47 48 #[repr(C)] 49 pub struct FluentNumberOptionsRaw { 50 pub style: FluentNumberStyleRaw, 51 pub currency: nsCString, 52 pub currency_display: FluentNumberCurrencyDisplayStyleRaw, 53 pub use_grouping: bool, 54 pub minimum_integer_digits: usize, 55 pub minimum_fraction_digits: usize, 56 pub maximum_fraction_digits: usize, 57 pub minimum_significant_digits: isize, 58 pub maximum_significant_digits: isize, 59 } 60 61 fn get_number_option(val: Option<usize>, min: usize, max: usize, default: usize) -> usize { 62 if let Some(val) = val { 63 if val >= min && val <= max { 64 val 65 } else { 66 default 67 } 68 } else { 69 default 70 } 71 } 72 73 impl From<&FluentNumberOptions> for FluentNumberOptionsRaw { 74 fn from(input: &FluentNumberOptions) -> Self { 75 let currency: nsCString = if let Some(ref currency) = input.currency { 76 currency.into() 77 } else { 78 nsCString::new() 79 }; 80 81 //XXX: This should be fetched from currency table. 82 let currency_digits = 2; 83 84 // Keep it aligned with ECMA402 NumberFormat logic. 85 let minfd_default = if input.style == FluentNumberStyle::Currency { 86 currency_digits 87 } else { 88 0 89 }; 90 let maxfd_default = match input.style { 91 FluentNumberStyle::Decimal => 3, 92 FluentNumberStyle::Currency => currency_digits, 93 FluentNumberStyle::Percent => 0, 94 }; 95 let minid = get_number_option(input.minimum_integer_digits, 1, 21, 1); 96 let minfd = get_number_option(input.minimum_fraction_digits, 0, 20, minfd_default); 97 let maxfd_actual_default = std::cmp::max(minfd, maxfd_default); 98 let maxfd = get_number_option( 99 input.maximum_fraction_digits, 100 minfd, 101 20, 102 maxfd_actual_default, 103 ); 104 105 let (minsd, maxsd) = if input.minimum_significant_digits.is_some() 106 || input.maximum_significant_digits.is_some() 107 { 108 let minsd = get_number_option(input.minimum_significant_digits, 1, 21, 1); 109 let maxsd = get_number_option(input.maximum_significant_digits, minsd, 21, 21); 110 (minsd as isize, maxsd as isize) 111 } else { 112 (-1, -1) 113 }; 114 115 Self { 116 style: input.style.into(), 117 currency, 118 currency_display: input.currency_display.into(), 119 use_grouping: input.use_grouping, 120 minimum_integer_digits: minid, 121 minimum_fraction_digits: minfd, 122 maximum_fraction_digits: maxfd, 123 minimum_significant_digits: minsd, 124 maximum_significant_digits: maxsd, 125 } 126 } 127 } 128 129 pub enum RawDateTimeFormatter {} 130 131 extern "C" { 132 pub fn FluentBuiltInNumberFormatterCreate( 133 locale: &nsCString, 134 options: &FluentNumberOptionsRaw, 135 ) -> *mut RawNumberFormatter; 136 pub fn FluentBuiltInNumberFormatterFormat( 137 formatter: *const RawNumberFormatter, 138 input: f64, 139 out_count: &mut usize, 140 out_capacity: &mut usize, 141 ) -> *mut u8; 142 pub fn FluentBuiltInNumberFormatterDestroy(formatter: *mut RawNumberFormatter); 143 144 pub fn FluentBuiltInDateTimeFormatterCreate( 145 locale: &nsCString, 146 options: FluentDateTimeOptions, 147 ) -> *mut RawDateTimeFormatter; 148 pub fn FluentBuiltInDateTimeFormatterFormat( 149 formatter: *const RawDateTimeFormatter, 150 input: f64, 151 out_count: &mut u32, 152 ) -> *mut u8; 153 pub fn FluentBuiltInDateTimeFormatterDestroy(formatter: *mut RawDateTimeFormatter); 154 }