summaryrefslogtreecommitdiffstats
path: root/intl/icu_capi/src/normalizer_properties.rs
blob: dbb1dfbdbc1fffbf5639de449cb88727ffc0dba6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

#[diplomat::bridge]
pub mod ffi {
    use crate::{errors::ffi::ICU4XError, provider::ffi::ICU4XDataProvider};
    use alloc::boxed::Box;
    use icu_normalizer::properties::{
        CanonicalCombiningClassMap, CanonicalComposition, CanonicalDecomposition, Decomposed,
    };

    /// Lookup of the Canonical_Combining_Class Unicode property
    #[diplomat::opaque]
    #[diplomat::rust_link(icu::normalizer::properties::CanonicalCombiningClassMap, Struct)]
    pub struct ICU4XCanonicalCombiningClassMap(pub CanonicalCombiningClassMap);

    impl ICU4XCanonicalCombiningClassMap {
        /// Construct a new ICU4XCanonicalCombiningClassMap instance for NFC
        #[diplomat::rust_link(
            icu::normalizer::properties::CanonicalCombiningClassMap::new,
            FnInStruct
        )]
        pub fn create(
            provider: &ICU4XDataProvider,
        ) -> Result<Box<ICU4XCanonicalCombiningClassMap>, ICU4XError> {
            Ok(Box::new(ICU4XCanonicalCombiningClassMap(
                call_constructor!(
                    CanonicalCombiningClassMap::new [r => Ok(r)],
                    CanonicalCombiningClassMap::try_new_with_any_provider,
                    CanonicalCombiningClassMap::try_new_with_buffer_provider,
                    provider
                )?,
            )))
        }

        #[diplomat::rust_link(
            icu::normalizer::properties::CanonicalCombiningClassMap::get,
            FnInStruct
        )]
        #[diplomat::rust_link(
            icu::properties::properties::CanonicalCombiningClass,
            Struct,
            compact
        )]
        pub fn get(&self, ch: char) -> u8 {
            self.0.get(ch).0
        }
        #[diplomat::rust_link(
            icu::normalizer::properties::CanonicalCombiningClassMap::get32,
            FnInStruct
        )]
        #[diplomat::rust_link(
            icu::properties::properties::CanonicalCombiningClass,
            Struct,
            compact
        )]
        pub fn get32(&self, ch: u32) -> u8 {
            self.0.get32(ch).0
        }
    }

    /// The raw canonical composition operation.
    ///
    /// Callers should generally use ICU4XComposingNormalizer unless they specifically need raw composition operations
    #[diplomat::opaque]
    #[diplomat::rust_link(icu::normalizer::properties::CanonicalComposition, Struct)]
    pub struct ICU4XCanonicalComposition(pub CanonicalComposition);

    impl ICU4XCanonicalComposition {
        /// Construct a new ICU4XCanonicalComposition instance for NFC
        #[diplomat::rust_link(icu::normalizer::properties::CanonicalComposition::new, FnInStruct)]
        pub fn create(
            provider: &ICU4XDataProvider,
        ) -> Result<Box<ICU4XCanonicalComposition>, ICU4XError> {
            Ok(Box::new(ICU4XCanonicalComposition(call_constructor!(
                CanonicalComposition::new [r => Ok(r)],
                CanonicalComposition::try_new_with_any_provider,
                CanonicalComposition::try_new_with_buffer_provider,
                provider,
            )?)))
        }

        /// Performs canonical composition (including Hangul) on a pair of characters
        /// or returns NUL if these characters don’t compose. Composition exclusions are taken into account.
        #[diplomat::rust_link(
            icu::normalizer::properties::CanonicalComposition::compose,
            FnInStruct
        )]
        pub fn compose(&self, starter: char, second: char) -> char {
            self.0.compose(starter, second).unwrap_or('\0')
        }
    }

    /// The outcome of non-recursive canonical decomposition of a character.
    /// `second` will be NUL when the decomposition expands to a single character
    /// (which may or may not be the original one)
    #[diplomat::rust_link(icu::normalizer::properties::Decomposed, Enum)]
    pub struct ICU4XDecomposed {
        first: char,
        second: char,
    }

    /// The raw (non-recursive) canonical decomposition operation.
    ///
    /// Callers should generally use ICU4XDecomposingNormalizer unless they specifically need raw composition operations
    #[diplomat::opaque]
    #[diplomat::rust_link(icu::normalizer::properties::CanonicalDecomposition, Struct)]
    pub struct ICU4XCanonicalDecomposition(pub CanonicalDecomposition);

    impl ICU4XCanonicalDecomposition {
        /// Construct a new ICU4XCanonicalDecomposition instance for NFC
        #[diplomat::rust_link(icu::normalizer::properties::CanonicalDecomposition::new, FnInStruct)]
        pub fn create(
            provider: &ICU4XDataProvider,
        ) -> Result<Box<ICU4XCanonicalDecomposition>, ICU4XError> {
            Ok(Box::new(ICU4XCanonicalDecomposition(call_constructor!(
                CanonicalDecomposition::new [r => Ok(r)],
                CanonicalDecomposition::try_new_with_any_provider,
                CanonicalDecomposition::try_new_with_buffer_provider,
                provider,
            )?)))
        }

        /// Performs non-recursive canonical decomposition (including for Hangul).
        #[diplomat::rust_link(
            icu::normalizer::properties::CanonicalDecomposition::decompose,
            FnInStruct
        )]
        pub fn decompose(&self, c: char) -> ICU4XDecomposed {
            match self.0.decompose(c) {
                Decomposed::Default => ICU4XDecomposed {
                    first: c,
                    second: '\0',
                },
                Decomposed::Singleton(s) => ICU4XDecomposed {
                    first: s,
                    second: '\0',
                },
                Decomposed::Expansion(first, second) => ICU4XDecomposed { first, second },
            }
        }
    }
}