Coverage Report

Created: 2025-11-16 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/icu_capi-1.5.1/src/pluralrules.rs
Line
Count
Source
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5
#[diplomat::bridge]
6
pub mod ffi {
7
    use alloc::boxed::Box;
8
9
    use fixed_decimal::FixedDecimal;
10
    use icu_plurals::{PluralCategory, PluralOperands, PluralRules};
11
12
    use crate::{locale::ffi::ICU4XLocale, provider::ffi::ICU4XDataProvider};
13
14
    use crate::errors::ffi::ICU4XError;
15
16
    #[diplomat::rust_link(icu::plurals::PluralCategory, Enum)]
17
    #[diplomat::enum_convert(PluralCategory)]
18
    pub enum ICU4XPluralCategory {
19
        Zero,
20
        One,
21
        Two,
22
        Few,
23
        Many,
24
        Other,
25
    }
26
27
    impl ICU4XPluralCategory {
28
        /// Construct from a string in the format
29
        /// [specified in TR35](https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules)
30
        #[diplomat::rust_link(icu::plurals::PluralCategory::get_for_cldr_string, FnInEnum)]
31
        #[diplomat::rust_link(icu::plurals::PluralCategory::get_for_cldr_bytes, FnInEnum)]
32
0
        pub fn get_for_cldr_string(s: &DiplomatStr) -> Option<ICU4XPluralCategory> {
33
0
            PluralCategory::get_for_cldr_bytes(s).map(Into::into)
34
0
        }
35
    }
36
37
    #[diplomat::rust_link(icu::plurals::PluralRules, Struct)]
38
    #[diplomat::opaque]
39
    pub struct ICU4XPluralRules(PluralRules);
40
41
    impl ICU4XPluralRules {
42
        /// Construct an [`ICU4XPluralRules`] for the given locale, for cardinal numbers
43
        #[diplomat::rust_link(icu::plurals::PluralRules::try_new_cardinal, FnInStruct)]
44
        #[diplomat::rust_link(icu::plurals::PluralRules::try_new, FnInStruct, hidden)]
45
        #[diplomat::rust_link(icu::plurals::PluralRuleType, Enum, hidden)]
46
        #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "cardinal")]
47
0
        pub fn create_cardinal(
48
0
            provider: &ICU4XDataProvider,
49
0
            locale: &ICU4XLocale,
50
0
        ) -> Result<Box<ICU4XPluralRules>, ICU4XError> {
51
0
            let locale = locale.to_datalocale();
52
0
            Ok(Box::new(ICU4XPluralRules(call_constructor!(
53
                PluralRules::try_new_cardinal,
54
                PluralRules::try_new_cardinal_with_any_provider,
55
                PluralRules::try_new_cardinal_with_buffer_provider,
56
                provider,
57
0
                &locale
58
0
            )?)))
59
0
        }
60
61
        /// Construct an [`ICU4XPluralRules`] for the given locale, for ordinal numbers
62
        #[diplomat::rust_link(icu::plurals::PluralRules::try_new_ordinal, FnInStruct)]
63
        #[diplomat::rust_link(icu::plurals::PluralRules::try_new, FnInStruct, hidden)]
64
        #[diplomat::rust_link(icu::plurals::PluralRuleType, Enum, hidden)]
65
        #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "ordinal")]
66
0
        pub fn create_ordinal(
67
0
            provider: &ICU4XDataProvider,
68
0
            locale: &ICU4XLocale,
69
0
        ) -> Result<Box<ICU4XPluralRules>, ICU4XError> {
70
0
            let locale = locale.to_datalocale();
71
0
            Ok(Box::new(ICU4XPluralRules(call_constructor!(
72
                PluralRules::try_new_ordinal,
73
                PluralRules::try_new_ordinal_with_any_provider,
74
                PluralRules::try_new_ordinal_with_buffer_provider,
75
                provider,
76
0
                &locale
77
0
            )?)))
78
0
        }
79
80
        /// Get the category for a given number represented as operands
81
        #[diplomat::rust_link(icu::plurals::PluralRules::category_for, FnInStruct)]
82
0
        pub fn category_for(&self, op: &ICU4XPluralOperands) -> ICU4XPluralCategory {
83
0
            self.0.category_for(op.0).into()
84
0
        }
85
86
        /// Get all of the categories needed in the current locale
87
        #[diplomat::rust_link(icu::plurals::PluralRules::categories, FnInStruct)]
88
        #[diplomat::attr(supports = accessors, getter)]
89
0
        pub fn categories(&self) -> ICU4XPluralCategories {
90
0
            ICU4XPluralCategories::from_iter(self.0.categories())
91
0
        }
92
    }
93
94
    #[diplomat::opaque]
95
    #[diplomat::rust_link(icu::plurals::PluralOperands, Struct)]
96
    pub struct ICU4XPluralOperands(pub icu_plurals::PluralOperands);
97
98
    impl ICU4XPluralOperands {
99
        /// Construct for a given string representing a number
100
        #[diplomat::rust_link(icu::plurals::PluralOperands::from_str, FnInStruct)]
101
        #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_string")]
102
0
        pub fn create_from_string(s: &DiplomatStr) -> Result<Box<ICU4XPluralOperands>, ICU4XError> {
103
0
            Ok(Box::new(ICU4XPluralOperands(PluralOperands::from(
104
                // XXX should this have its own errors?
105
0
                &FixedDecimal::try_from(s).map_err(|_| ICU4XError::PluralsParserError)?,
106
            ))))
107
0
        }
108
109
        /// Construct from a FixedDecimal
110
        ///
111
        /// Retains at most 18 digits each from the integer and fraction parts.
112
        #[cfg(feature = "icu_decimal")]
113
        #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_fixed_decimal")]
114
0
        pub fn create_from_fixed_decimal(
115
0
            x: &crate::fixed_decimal::ffi::ICU4XFixedDecimal,
116
0
        ) -> Box<Self> {
117
0
            Box::new(Self((&x.0).into()))
118
0
        }
119
    }
120
121
    #[diplomat::out]
122
    pub struct ICU4XPluralCategories {
123
        pub zero: bool,
124
        pub one: bool,
125
        pub two: bool,
126
        pub few: bool,
127
        pub many: bool,
128
        pub other: bool,
129
    }
130
131
    impl ICU4XPluralCategories {
132
0
        fn from_iter(i: impl Iterator<Item = PluralCategory>) -> Self {
133
0
            i.fold(
134
0
                ICU4XPluralCategories {
135
0
                    zero: false,
136
0
                    one: false,
137
0
                    two: false,
138
0
                    few: false,
139
0
                    many: false,
140
0
                    other: false,
141
0
                },
142
0
                |mut categories, category| {
143
0
                    match category {
144
0
                        PluralCategory::Zero => categories.zero = true,
145
0
                        PluralCategory::One => categories.one = true,
146
0
                        PluralCategory::Two => categories.two = true,
147
0
                        PluralCategory::Few => categories.few = true,
148
0
                        PluralCategory::Many => categories.many = true,
149
0
                        PluralCategory::Other => categories.other = true,
150
                    };
151
0
                    categories
152
0
                },
153
            )
154
0
        }
155
    }
156
}