11/* Access to the unicode database.
22 See also: https://docs.python.org/3/library/unicodedata.html
33*/
4- use crate :: vm:: { PyObjectRef , PyPayload , VirtualMachine } ;
4+ use crate :: vm:: {
5+ builtins:: PyStr , convert:: TryFromBorrowedObject , PyObject , PyObjectRef , PyPayload , PyResult ,
6+ VirtualMachine ,
7+ } ;
58
69pub fn make_module ( vm : & VirtualMachine ) -> PyObjectRef {
710 let module = unicodedata:: make_module ( vm) ;
@@ -28,6 +31,30 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
2831 module
2932}
3033
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+
3158#[ pymodule]
3259mod unicodedata {
3360 use crate :: vm:: {
@@ -63,11 +90,7 @@ mod unicodedata {
6390 vm. new_type_error ( "argument must be an unicode character, not str" . to_owned ( ) )
6491 } ) ?;
6592
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) )
7194 }
7295 }
7396
@@ -112,40 +135,41 @@ mod unicodedata {
112135 }
113136
114137 #[ 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 > {
116143 let bidi = match self . extract_char ( character, vm) ? {
117144 Some ( c) => BidiClass :: of ( c) . abbr_name ( ) ,
118145 None => "" ,
119146 } ;
120- Ok ( bidi. to_owned ( ) )
147+ Ok ( bidi)
121148 }
122149
123150 /// NOTE: This function uses 9.0.0 database instead of 3.2.0
124151 #[ 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 > {
126157 Ok ( self
127158 . extract_char ( character, vm) ?
128159 . map_or ( EastAsianWidth :: Neutral , |c| c. east_asian_width ( ) )
129- . abbr_name ( )
130- . to_owned ( ) )
160+ . abbr_name ( ) )
131161 }
132162
133163 #[ 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 :: * ;
140166 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 > ( ) ,
147172 } ;
148-
149173 Ok ( normalized_text)
150174 }
151175
0 commit comments