@@ -318,50 +318,48 @@ fn check_validity(label: &str, config: Config, errors: &mut Errors) {
318
318
// V8: Bidi rules are checked inside `processing()`
319
319
}
320
320
321
- /// http://www.unicode.org/reports/tr46/#Processing
322
- fn processing (
323
- domain : & str ,
324
- config : Config ,
325
- normalized : & mut String ,
326
- output : & mut String ,
327
- ) -> Errors {
328
- // Weed out the simple cases: only allow all lowercase ASCII characters and digits where none
329
- // of the labels start with PUNYCODE_PREFIX and labels don't start or end with hyphen.
330
- let ( mut prev, mut simple, mut puny_prefix) = ( '?' , !domain. is_empty ( ) , 0 ) ;
321
+ // Detect simple cases: all lowercase ASCII characters and digits where none
322
+ // of the labels start with PUNYCODE_PREFIX and labels don't start or end with hyphen.
323
+ fn is_simple ( domain : & str ) -> bool {
324
+ if domain. is_empty ( ) {
325
+ return false ;
326
+ }
327
+ let ( mut prev, mut puny_prefix) = ( '?' , 0 ) ;
331
328
for c in domain. chars ( ) {
332
329
if c == '.' {
333
330
if prev == '-' {
334
- simple = false ;
335
- break ;
331
+ return false ;
336
332
}
337
333
puny_prefix = 0 ;
338
334
continue ;
339
335
} else if puny_prefix == 0 && c == '-' {
340
- simple = false ;
341
- break ;
336
+ return false ;
342
337
} else if puny_prefix < 5 {
343
338
if c == [ 'x' , 'n' , '-' , '-' ] [ puny_prefix] {
344
339
puny_prefix += 1 ;
345
340
if puny_prefix == 4 {
346
- simple = false ;
347
- break ;
341
+ return false ;
348
342
}
349
343
} else {
350
344
puny_prefix = 5 ;
351
345
}
352
346
}
353
347
if !c. is_ascii_lowercase ( ) && !c. is_ascii_digit ( ) {
354
- simple = false ;
355
- break ;
348
+ return false ;
356
349
}
357
350
prev = c;
358
351
}
359
352
360
- if simple {
361
- output. push_str ( domain) ;
362
- return Errors :: default ( ) ;
363
- }
353
+ true
354
+ }
364
355
356
+ /// http://www.unicode.org/reports/tr46/#Processing
357
+ fn processing (
358
+ domain : & str ,
359
+ config : Config ,
360
+ normalized : & mut String ,
361
+ output : & mut String ,
362
+ ) -> Errors {
365
363
normalized. clear ( ) ;
366
364
let mut errors = Errors :: default ( ) ;
367
365
let offset = output. len ( ) ;
@@ -447,11 +445,13 @@ impl Idna {
447
445
}
448
446
}
449
447
450
- /// http://www.unicode.org/reports/tr46/#ToASCII
451
- #[ allow( clippy:: wrong_self_convention) ]
452
- pub fn to_ascii < ' a > ( & ' a mut self , domain : & str , out : & mut String ) -> Result < ( ) , Errors > {
453
- let mut errors = processing ( domain, self . config , & mut self . normalized , & mut self . output ) ;
454
-
448
+ pub fn to_ascii_inner ( & mut self , domain : & str , out : & mut String ) -> Errors {
449
+ if is_simple ( domain) {
450
+ out. push_str ( domain) ;
451
+ return Errors :: default ( ) ;
452
+ }
453
+ let mut errors = processing ( domain, self . config , & mut self . normalized , out) ;
454
+ self . output = std:: mem:: replace ( out, String :: with_capacity ( out. len ( ) ) ) ;
455
455
let mut first = true ;
456
456
for label in self . output . split ( '.' ) {
457
457
if !first {
@@ -470,6 +470,13 @@ impl Idna {
470
470
}
471
471
}
472
472
}
473
+ errors
474
+ }
475
+
476
+ /// http://www.unicode.org/reports/tr46/#ToASCII
477
+ #[ allow( clippy:: wrong_self_convention) ]
478
+ pub fn to_ascii < ' a > ( & ' a mut self , domain : & str , out : & mut String ) -> Result < ( ) , Errors > {
479
+ let mut errors = self . to_ascii_inner ( domain, out) ;
473
480
474
481
if self . config . verify_dns_length {
475
482
let domain = if out. ends_with ( '.' ) {
@@ -491,6 +498,10 @@ impl Idna {
491
498
/// http://www.unicode.org/reports/tr46/#ToUnicode
492
499
#[ allow( clippy:: wrong_self_convention) ]
493
500
pub fn to_unicode < ' a > ( & ' a mut self , domain : & str , out : & mut String ) -> Result < ( ) , Errors > {
501
+ if is_simple ( domain) {
502
+ out. push_str ( domain) ;
503
+ return Errors :: default ( ) . into ( ) ;
504
+ }
494
505
processing ( domain, self . config , & mut self . normalized , out) . into ( )
495
506
}
496
507
}
0 commit comments