1
1
/* Access to the unicode database.
2
2
See also: https://docs.python.org/3/library/unicodedata.html
3
3
*/
4
- use crate :: vm:: { PyObjectRef , PyPayload , VirtualMachine } ;
4
+ use crate :: vm:: {
5
+ builtins:: PyStr , convert:: TryFromBorrowedObject , PyObject , PyObjectRef , PyPayload , PyResult ,
6
+ VirtualMachine ,
7
+ } ;
5
8
6
9
pub fn make_module ( vm : & VirtualMachine ) -> PyObjectRef {
7
10
let module = unicodedata:: make_module ( vm) ;
@@ -28,6 +31,30 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
28
31
module
29
32
}
30
33
34
+ enum NormalizeForm {
35
+ Nfc ,
36
+ Nfkc ,
37
+ Nfd ,
38
+ Nfkd ,
39
+ }
40
+
41
+ impl TryFromBorrowedObject for NormalizeForm {
42
+ fn try_from_borrowed_object ( vm : & VirtualMachine , obj : & PyObject ) -> PyResult < Self > {
43
+ obj. try_value_with (
44
+ |form : & PyStr | {
45
+ Ok ( match form. as_str ( ) {
46
+ "NFC" => NormalizeForm :: Nfc ,
47
+ "NFKC" => NormalizeForm :: Nfkc ,
48
+ "NFD" => NormalizeForm :: Nfd ,
49
+ "NFKD" => NormalizeForm :: Nfkd ,
50
+ _ => return Err ( vm. new_value_error ( "invalid normalization form" . to_owned ( ) ) ) ,
51
+ } )
52
+ } ,
53
+ vm,
54
+ )
55
+ }
56
+ }
57
+
31
58
#[ pymodule]
32
59
mod unicodedata {
33
60
use crate :: vm:: {
@@ -63,11 +90,7 @@ mod unicodedata {
63
90
vm. new_type_error ( "argument must be an unicode character, not str" . to_owned ( ) )
64
91
} ) ?;
65
92
66
- if self . check_age ( c) {
67
- Ok ( Some ( c) )
68
- } else {
69
- Ok ( None )
70
- }
93
+ Ok ( self . check_age ( c) . then_some ( c) )
71
94
}
72
95
}
73
96
@@ -112,40 +135,41 @@ mod unicodedata {
112
135
}
113
136
114
137
#[ pymethod]
115
- fn bidirectional ( & self , character : PyStrRef , vm : & VirtualMachine ) -> PyResult < String > {
138
+ fn bidirectional (
139
+ & self ,
140
+ character : PyStrRef ,
141
+ vm : & VirtualMachine ,
142
+ ) -> PyResult < & ' static str > {
116
143
let bidi = match self . extract_char ( character, vm) ? {
117
144
Some ( c) => BidiClass :: of ( c) . abbr_name ( ) ,
118
145
None => "" ,
119
146
} ;
120
- Ok ( bidi. to_owned ( ) )
147
+ Ok ( bidi)
121
148
}
122
149
123
150
/// NOTE: This function uses 9.0.0 database instead of 3.2.0
124
151
#[ pymethod]
125
- fn east_asian_width ( & self , character : PyStrRef , vm : & VirtualMachine ) -> PyResult < String > {
152
+ fn east_asian_width (
153
+ & self ,
154
+ character : PyStrRef ,
155
+ vm : & VirtualMachine ,
156
+ ) -> PyResult < & ' static str > {
126
157
Ok ( self
127
158
. extract_char ( character, vm) ?
128
159
. map_or ( EastAsianWidth :: Neutral , |c| c. east_asian_width ( ) )
129
- . abbr_name ( )
130
- . to_owned ( ) )
160
+ . abbr_name ( ) )
131
161
}
132
162
133
163
#[ pymethod]
134
- fn normalize (
135
- & self ,
136
- form : PyStrRef ,
137
- unistr : PyStrRef ,
138
- vm : & VirtualMachine ,
139
- ) -> PyResult < String > {
164
+ fn normalize ( & self , form : super :: NormalizeForm , unistr : PyStrRef ) -> PyResult < String > {
165
+ use super :: NormalizeForm :: * ;
140
166
let text = unistr. as_str ( ) ;
141
- let normalized_text = match form. as_str ( ) {
142
- "NFC" => text. nfc ( ) . collect :: < String > ( ) ,
143
- "NFKC" => text. nfkc ( ) . collect :: < String > ( ) ,
144
- "NFD" => text. nfd ( ) . collect :: < String > ( ) ,
145
- "NFKD" => text. nfkd ( ) . collect :: < String > ( ) ,
146
- _ => return Err ( vm. new_value_error ( "invalid normalization form" . to_owned ( ) ) ) ,
167
+ let normalized_text = match form {
168
+ Nfc => text. nfc ( ) . collect :: < String > ( ) ,
169
+ Nfkc => text. nfkc ( ) . collect :: < String > ( ) ,
170
+ Nfd => text. nfd ( ) . collect :: < String > ( ) ,
171
+ Nfkd => text. nfkd ( ) . collect :: < String > ( ) ,
147
172
} ;
148
-
149
173
Ok ( normalized_text)
150
174
}
151
175
0 commit comments