@@ -4,10 +4,11 @@ use crate::{
44 convert:: TryFromBorrowedObject ,
55 function:: OptionalOption ,
66} ;
7- use icu_casemap:: CaseMapper ;
8- use icu_locale:: LanguageIdentifier ;
7+ use icu_properties:: {
8+ CodePointSetData ,
9+ props:: { Alphabetic , ChangesWhenLowercased , ChangesWhenUppercased } ,
10+ } ;
911use num_traits:: { cast:: ToPrimitive , sign:: Signed } ;
10- use writeable:: Writeable ;
1112
1213use core:: ops:: Range ;
1314
@@ -133,8 +134,6 @@ where
133134}
134135
135136pub trait AnyChar : Copy {
136- fn is_lowercase ( self ) -> bool ;
137- fn is_uppercase ( self ) -> bool ;
138137 fn bytes_len ( self ) -> usize ;
139138}
140139
@@ -410,19 +409,17 @@ pub trait AnyStr {
410409 // _Py_bytes_islower
411410 // unicode_islower_impl
412411 fn py_islower ( & self ) -> bool {
412+ let case_change = CodePointSetData :: new :: < ChangesWhenLowercased > ( ) ;
413+ let alphabetic = CodePointSetData :: new :: < Alphabetic > ( ) ;
413414 let mut lower = false ;
414- let mut lowercased = String :: with_capacity ( self . bytes_len ( ) ) ;
415- let cm = CaseMapper :: new ( ) ;
416415 for chunk in self . as_bytes ( ) . utf8_chunks ( ) . map ( |c| c. valid ( ) ) {
417- let writer = cm. lowercase ( chunk, & LanguageIdentifier :: UNKNOWN ) ;
418- lowercased. clear ( ) ;
419- writer
420- . write_to ( & mut lowercased)
421- . expect ( "Writing to a buffer is infallible" ) ;
422- if chunk != lowercased {
416+ if chunk. chars ( ) . any ( |c| case_change. contains ( c) ) {
423417 return false ;
424418 }
425- lower = true ;
419+
420+ if !lower && chunk. chars ( ) . any ( |c| alphabetic. contains ( c) ) {
421+ lower = true ;
422+ }
426423 }
427424 lower
428425 }
@@ -431,19 +428,17 @@ pub trait AnyStr {
431428 // Py_bytes_isupper
432429 // unicode_isupper_impl
433430 fn py_isupper ( & self ) -> bool {
431+ let case_change = CodePointSetData :: new :: < ChangesWhenUppercased > ( ) ;
432+ let alphabetic = CodePointSetData :: new :: < Alphabetic > ( ) ;
434433 let mut upper = false ;
435- let mut uppercased = String :: with_capacity ( self . bytes_len ( ) ) ;
436- let cm = CaseMapper :: new ( ) ;
437434 for chunk in self . as_bytes ( ) . utf8_chunks ( ) . map ( |c| c. valid ( ) ) {
438- let writer = cm. uppercase ( chunk, & LanguageIdentifier :: UNKNOWN ) ;
439- uppercased. clear ( ) ;
440- writer
441- . write_to ( & mut uppercased)
442- . expect ( "Writing to a buffer is infallible" ) ;
443- if chunk != uppercased {
435+ if chunk. chars ( ) . any ( |c| case_change. contains ( c) ) {
444436 return false ;
445437 }
446- upper = true ;
438+
439+ if !upper && chunk. chars ( ) . any ( |c| alphabetic. contains ( c) ) {
440+ upper = true ;
441+ }
447442 }
448443 upper
449444 }
0 commit comments